hytos / DTI_PID / DTI_PID / QSymbolEditorDialog.py @ 35d6d96c
이력 | 보기 | 이력해설 | 다운로드 (15.4 KB)
1 |
# coding: utf-8
|
---|---|
2 |
from PyQt5 import QtCore, QtGui, QtWidgets |
3 |
from PyQt5.QtWidgets import * |
4 |
from PyQt5.QtGui import * |
5 |
from QtImageViewer import QtImageViewer |
6 |
import os |
7 |
import sqlite3 |
8 |
import sys |
9 |
import SG_DbHelper |
10 |
import symbol, SymbolBase |
11 |
import potrace |
12 |
|
13 |
import UI_SymbolEditor |
14 |
from AppDocData import AppDocData |
15 |
|
16 |
|
17 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands') |
18 |
import CropCommand, HandCommand, ZoomCommand, PenCommand, EraserCommand, AreaEraserCommand, OriginalPointCommand, ConnectionPointCommand |
19 |
|
20 |
|
21 |
class QSymbolEditorDialog(QDialog): |
22 |
FILE_NUMBER = 0
|
23 |
|
24 |
def __init__(self, parent, image, project): |
25 |
QDialog.__init__(self, parent)
|
26 |
|
27 |
self.image = image
|
28 |
self.project = project
|
29 |
self.ui = UI_SymbolEditor.Ui_Dialog()
|
30 |
self.ui.setupUi(self) |
31 |
self.setupImageViewer()
|
32 |
self.setupTools()
|
33 |
self.initForms()
|
34 |
self.initContents()
|
35 |
self.isAccepted = False |
36 |
self.dbHelper = SG_DbHelper.SG_DbHelper(self.project.getPath()) |
37 |
|
38 |
def setupImageViewer(self): |
39 |
x = self.ui.imageViewContainer.x()
|
40 |
y = self.ui.imageViewContainer.y()
|
41 |
width = self.ui.imageViewContainer.frameGeometry().width()
|
42 |
height = self.ui.imageViewContainer.frameGeometry().height()
|
43 |
self.ui.imageView = QtImageViewer()
|
44 |
self.ui.imageView.setGeometry(QtCore.QRect(0, y, height, height)) |
45 |
self.ui.imageView.aspectRatioMode = QtCore.Qt.KeepAspectRatio
|
46 |
self.ui.imageView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
47 |
self.ui.imageView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
48 |
self.ui.imageView.canZoom = True |
49 |
self.ui.imageView.canPan = True |
50 |
image = self.image.copy()
|
51 |
self.imgW = image.width()
|
52 |
self.imgH = image.height()
|
53 |
image = image.scaled(self.imgW, self.imgH) |
54 |
self.ui.imageView.setImage(image)
|
55 |
self.ui.imageViewerContainerLayout.addWidget(self.ui.imageView) |
56 |
|
57 |
def setupTools(self): |
58 |
self.ui.handButton.clicked.connect(self.handToolClickEvent) |
59 |
self.ui.penButton.clicked.connect(self.penToolClickEvent) |
60 |
self.ui.penWidthSpinBox.valueChanged.connect(self.penWidthChangedEvent) |
61 |
self.ui.eraserButton.clicked.connect(self.eraserToolClickEvent) |
62 |
self.ui.eraserSpinBox.valueChanged.connect(self.eraserWidthChangedEvent) |
63 |
self.ui.areaEraserButton.clicked.connect(self.areaEraserToolClickEvent) |
64 |
self.ui.zoomButton.clicked.connect(self.zoomToolClickEvent) |
65 |
self.ui.initZoomButton.clicked.connect(self.zoomInitToolClickEvent) |
66 |
self.ui.guidelineCheckbox.stateChanged.connect(self.guidelineStateChangedEvent) |
67 |
|
68 |
def initForms(self): |
69 |
self.ui.idLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[1-9]\d+$"))) |
70 |
self.ui.thresholdLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) # ([0-1]{1}[.])?[0-9]+ |
71 |
self.ui.minMatchPointLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) |
72 |
self.initIsOriginDetectComboBoxItems()
|
73 |
self.initOcrOptionComboBoxItems()
|
74 |
self.initDefaultSymbolDirectionComboBoxItems()
|
75 |
self.ui.addAdditionalSymbolButton.clicked.connect(self.addAdditionalSymbol) |
76 |
self.ui.addOriginalPointButton.clicked.connect(self.addOriginalPoint) |
77 |
self.ui.addConnectionPointButton.clicked.connect(self.addConnectionPoint) |
78 |
self.initBaseSymbolComboBoxItems()
|
79 |
self.initAdditionalSymbolComboBoxItems()
|
80 |
|
81 |
def initContents(self): |
82 |
self.ui.targetDBLineEdit.setText(self.project.getPath()+'/db/ITI_PID.db') |
83 |
#self.ui.isOriginDetectComboBox
|
84 |
#self.ui.ocrOptionComboBox
|
85 |
#self.ui.baseSymbolComboBox
|
86 |
#self.initBaseSymbolComboBoxItems()
|
87 |
#self.ui.defaultSymbolDirectionComboBox
|
88 |
#self.ui.additionalSymbolComboBox
|
89 |
|
90 |
def initIsOriginDetectComboBoxItems(self): |
91 |
self.ui.isOriginDetectComboBox.addItem("원본 도면", 0) |
92 |
self.ui.isOriginDetectComboBox.addItem("텍스트 제거 도면", 1) |
93 |
|
94 |
def initOcrOptionComboBoxItems(self): |
95 |
self.ui.ocrOptionComboBox.addItem("OCR 미적용", 0) |
96 |
self.ui.ocrOptionComboBox.addItem("일반 심볼", 1) |
97 |
self.ui.ocrOptionComboBox.addItem("Instrument 계통", 2) |
98 |
|
99 |
def initDefaultSymbolDirectionComboBoxItems(self): |
100 |
self.ui.defaultSymbolDirectionComboBox.addItem("상", 0) |
101 |
self.ui.defaultSymbolDirectionComboBox.addItem("하", 2) |
102 |
self.ui.defaultSymbolDirectionComboBox.addItem("좌", 3) |
103 |
self.ui.defaultSymbolDirectionComboBox.addItem("우", 1) |
104 |
|
105 |
def initBaseSymbolComboBoxItems(self): |
106 |
symbolNameList = AppDocData.instance().getSymbolNameList() |
107 |
symbolNameList.insert(0, "None") |
108 |
for name in symbolNameList: |
109 |
self.ui.baseSymbolComboBox.addItem(name)
|
110 |
|
111 |
def initAdditionalSymbolComboBoxItems(self): |
112 |
symbolNameList = AppDocData.instance().getSymbolNameList() |
113 |
symbolNameList.insert(0, "None") |
114 |
for name in symbolNameList: |
115 |
self.ui.additionalSymbolComboBox.addItem(name)
|
116 |
|
117 |
def removeConnectionPointCircles(self, circlePointList): |
118 |
for circlePoint in circlePointList: |
119 |
self.removeConnectionPointCircle(circlePoint)
|
120 |
|
121 |
def removeConnectionPointCircle(self, circlePoint): |
122 |
self.ui.imageView.scene.removeItem(self.ui.imageView.scene.itemAt(QtCore.QPointF(int(circlePoint.x()), int(circlePoint.y())), QTransform())) |
123 |
|
124 |
def showDialog(self): |
125 |
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) |
126 |
self.show()
|
127 |
self.exec_()
|
128 |
return self.isAccepted |
129 |
|
130 |
def makeFileName(self, originName, newName): |
131 |
imageFolderDir = self.project.getPath() + "\\image" |
132 |
imageDir = imageFolderDir + "\\" + newName + ".png" |
133 |
svgFolderDir = self.project.getPath() + "\\svg" |
134 |
svgDir = svgFolderDir + "\\" + newName + ".svg" |
135 |
if (os.path.exists(imageDir)) or (self.dbHelper.isExistFileName(imageDir) or (os.path.exists(svgDir))): |
136 |
self.FILE_NUMBER = self.FILE_NUMBER + 1 |
137 |
imgName = originName + "({})".format(self.FILE_NUMBER) |
138 |
return self.makeFileName(originName, imgName) |
139 |
else:
|
140 |
return newName
|
141 |
|
142 |
def makeSymbolData(self): |
143 |
symId = self.ui.idLineEdit.text()
|
144 |
name = self.ui.nameLineEdit.text()
|
145 |
type = self.ui.typeLineEdit.text()
|
146 |
self.FILE_NUMBER = 0 |
147 |
fileName = self.makeFileName(name, name)
|
148 |
path = self.project.getPath() + "\\image\\" + fileName + ".png" |
149 |
threshold = self.ui.thresholdLineEdit.text()
|
150 |
minMatchPoint = self.ui.minMatchPointLineEdit.text()
|
151 |
isDetectOnOrigin = self.ui.isOriginDetectComboBox.currentData()
|
152 |
rotationCount = self.ui.rotationCountSpinBox.value()
|
153 |
ocrOption = self.ui.ocrOptionComboBox.currentData()
|
154 |
isContainChild = 1 if self.ui.isContainChildCheckBox.isChecked() else 0 |
155 |
originalPoint = self.ui.originalPointLineEdit.text()
|
156 |
connectionPoint = self.makeConnectionPointListString()
|
157 |
### 기초심볼추가
|
158 |
baseSymbol = self.ui.baseSymbolComboBox.currentText()
|
159 |
### 부가심볼추가
|
160 |
additionalSymbol = self.makeAdditionalSymbolListString()
|
161 |
|
162 |
convertedThreshold = int(threshold) / 100.0 |
163 |
|
164 |
newSym = symbol.SymbolBase(int(symId), fileName, type, path, convertedThreshold, int(minMatchPoint), isDetectOnOrigin |
165 |
, rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol) |
166 |
|
167 |
return newSym
|
168 |
|
169 |
def makeAdditionalSymbolListString(self): |
170 |
ret = ""
|
171 |
listItems = [] |
172 |
for index in range(self.ui.additionalSymbolListWidget.count()): |
173 |
listItems.append(self.ui.additionalSymbolListWidget.item(index))
|
174 |
if listItems is not None: |
175 |
for index in range(len(listItems)): |
176 |
item = listItems[index] |
177 |
text = item.text() |
178 |
if index != 0: |
179 |
ret = ret + "/"
|
180 |
ret = ret + text |
181 |
return ret
|
182 |
|
183 |
def makeConnectionPointListString(self): |
184 |
ret = ""
|
185 |
listItems = [] |
186 |
for index in range(self.ui.connectionPointList.count()): |
187 |
listItems.append(self.ui.connectionPointList.item(index))
|
188 |
if listItems is not None: |
189 |
for index in range(len(listItems)): |
190 |
item = listItems[index] |
191 |
text = item.text() |
192 |
if index != 0: |
193 |
ret = ret + "/"
|
194 |
ret = ret + text |
195 |
return ret
|
196 |
|
197 |
def accept(self): |
198 |
print("save")
|
199 |
|
200 |
isValid, exceptionMsg = self.isValidSymbolInfo()
|
201 |
if isValid:
|
202 |
print("valid symbol info")
|
203 |
isAdded, fileName, imagePath = self.dbHelper.insertSymbol(self.makeSymbolData()) |
204 |
|
205 |
if isAdded:
|
206 |
image = self.ui.imageView.image()
|
207 |
if image is not None: |
208 |
image.save(imagePath, 'PNG')
|
209 |
potrace.convertImageToSvg(imagePath, self.project.getPath()+"\\svg\\" + fileName + ".svg") |
210 |
self.isAccepted = True |
211 |
else:
|
212 |
QMessageBox.about(self.ui.buttonBox, "알림", "심볼 저장 과정 중 문제가 발생했습니다.") |
213 |
QDialog.accept(self)
|
214 |
else:
|
215 |
print("invalid symbol info")
|
216 |
QMessageBox.about(self.ui.buttonBox, "알림", exceptionMsg) |
217 |
|
218 |
def cancel(self): |
219 |
print("cancel")
|
220 |
self.isAccepted = Flase
|
221 |
QDialog.cancel(self)
|
222 |
|
223 |
def keyPressEvent(self, event): |
224 |
if event.key() == QtCore.Qt.Key_Delete:
|
225 |
selectedItems = self.ui.connectionPointList.selectedItems()
|
226 |
if selectedItems is not None: |
227 |
for item in selectedItems: |
228 |
text = item.text() |
229 |
x = int(text.split(",")[0]) |
230 |
y = int(text.split(",")[1]) |
231 |
self.removeConnectionPointCircle(QtCore.QPointF(x, y))
|
232 |
self.ui.connectionPointList.takeItem(self.ui.connectionPointList.row(item)) |
233 |
|
234 |
def handToolClickEvent(self, event): |
235 |
print("hand tool clicked")
|
236 |
self.ui.imageView.command = HandCommand.HandCommand(self.ui.imageView) |
237 |
|
238 |
def zoomInitToolClickEvent(self, event): |
239 |
print("zoom init tool clicked")
|
240 |
self.ui.imageView.command = None |
241 |
self.ui.imageView.zoomImageInit()
|
242 |
|
243 |
def zoomToolClickEvent(self, event): |
244 |
print("zoom tool clicked")
|
245 |
self.ui.imageView.command = ZoomCommand.ZoomCommand(self.ui.imageView) |
246 |
|
247 |
def penToolClickEvent(self, event): |
248 |
print("Pen")
|
249 |
width = self.ui.toolWidget.findChild(QSpinBox, 'penWidthSpinBox').value() |
250 |
self.ui.imageView.command = PenCommand.PenCommand(self.ui.imageView) |
251 |
self.ui.imageView.command.width = width
|
252 |
|
253 |
def penWidthChangedEvent(self, value): |
254 |
print("Pen Width " + str(value)) |
255 |
if self.ui.imageView.command is not None and type(self.ui.imageView.command) is PenCommand.PenCommand: |
256 |
self.ui.imageView.command.width = value
|
257 |
|
258 |
def eraserToolClickEvent(self, event): |
259 |
print("eraser")
|
260 |
width = self.ui.toolWidget.findChild(QSpinBox, 'eraserSpinBox').value() |
261 |
self.ui.imageView.command = EraserCommand.EraserCommand(self.ui.imageView) |
262 |
self.ui.imageView.command.width = width
|
263 |
|
264 |
def eraserWidthChangedEvent(self, value): |
265 |
print("eraser " + str(value)) |
266 |
if self.ui.imageView.command is not None and type(self.ui.imageView.command) is EraserCommand.EraserCommand: |
267 |
self.ui.imageView.command.width = value
|
268 |
|
269 |
def areaEraserToolClickEvent(self, event): |
270 |
print("area eraser")
|
271 |
self.ui.imageView.command = AreaEraserCommand.AreaEraserCommand(self.ui.imageView) |
272 |
|
273 |
def guidelineStateChangedEvent(self, value): |
274 |
if self.ui.guidelineCheckbox.isChecked(): |
275 |
self.ui.imageView.showGuideline(True) |
276 |
else:
|
277 |
self.ui.imageView.showGuideline(False) |
278 |
|
279 |
def addAdditionalSymbol(self, event): |
280 |
print("addAdditionalSymbol")
|
281 |
additionalSymbolIndex = self.ui.additionalSymbolComboBox.currentIndex()
|
282 |
if additionalSymbolIndex != 0: |
283 |
print("Symbol Selected")
|
284 |
direction = self.ui.defaultSymbolDirectionComboBox.currentText()
|
285 |
symbolName = self.ui.additionalSymbolComboBox.currentText()
|
286 |
text = "{},{}".format(direction, symbolName)
|
287 |
|
288 |
if self.isAlreadyAdded(text): |
289 |
QMessageBox.about(self.ui.buttonBox, "알림", "이미 추가된 아이템입니다.") |
290 |
else:
|
291 |
self.ui.additionalSymbolListWidget.addItem(text)
|
292 |
|
293 |
def isAlreadyAdded(self, text): |
294 |
for index in range(self.ui.additionalSymbolListWidget.count()): |
295 |
item = self.ui.additionalSymbolListWidget.item(index)
|
296 |
if item.text() == text:
|
297 |
return True |
298 |
return False |
299 |
|
300 |
def addOriginalPoint(self, event): |
301 |
print("addOriginalPoint")
|
302 |
self.ui.imageView.command = OriginalPointCommand.OriginalPointCommand(self.ui.imageView, self.ui.originalPointLineEdit) |
303 |
|
304 |
def addConnectionPoint(self, event): |
305 |
print("addConnectionPoint")
|
306 |
self.ui.imageView.command = ConnectionPointCommand.ConnectionPointCommand(self.ui.imageView, self.ui.connectionPointLineEdit, self.ui.connectionPointList) |
307 |
|
308 |
def isValidSymbolInfo(self): |
309 |
print("isValid")
|
310 |
EXCEPTION_MSG_FORMAT = "{} 입력을 확인해주세요."
|
311 |
EXCEPTION_MSG_DUPLICATED_FORMAT = "이미 저장된 {} 값입니다."
|
312 |
infoTitle = ""
|
313 |
|
314 |
idText = self.ui.idLineEdit.text()
|
315 |
id = int(idText) if idText else -1 |
316 |
if (id == -1 or id < 100): |
317 |
infoTitle = self.ui.idLabel.text()
|
318 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
319 |
|
320 |
if self.dbHelper.isExistData('symId', id): |
321 |
infoTitle = self.ui.idLabel.text()
|
322 |
return (False, EXCEPTION_MSG_DUPLICATED_FORMAT.format(infoTitle)) |
323 |
|
324 |
if not self.ui.nameLineEdit.text(): |
325 |
infoTitle = self.ui.nameLabel.text()
|
326 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
327 |
|
328 |
#if not self.ui.typeLineEdit.text():
|
329 |
# infoTitle = self.ui.typeLabel.text()
|
330 |
# return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
|
331 |
|
332 |
thresholdText = self.ui.thresholdLineEdit.text()
|
333 |
threshold = float(thresholdText) if thresholdText else -1 |
334 |
if not(threshold >= 0 and threshold <= 100): |
335 |
infoTitle = self.ui.thresholdLabel.text()
|
336 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
337 |
|
338 |
minMatchPointText = self.ui.minMatchPointLineEdit.text()
|
339 |
minMatchPoint = float(minMatchPointText) if minMatchPointText else -1 |
340 |
if not(minMatchPoint >= 0): |
341 |
infoTitle = self.ui.minMatchPointLabel.text()
|
342 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
343 |
|
344 |
if self.ui.baseSymbolComboBox.currentIndex() == 0: #default value(None) index |
345 |
infoTitle = self.ui.baseSymbolLabel.text()
|
346 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
347 |
|
348 |
#Additional Symbol is Nullable
|
349 |
|
350 |
if not self.ui.originalPointLineEdit.text() or self.ui.imageView.isOriginalPointSelected == False: |
351 |
infoTitle = self.ui.originalPointLabel.text()
|
352 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
353 |
|
354 |
if not (self.ui.connectionPointList.count() > 0): |
355 |
infoTitle = self.ui.connectionPointLabel.text()
|
356 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
357 |
|
358 |
return True, None |