개정판 ce604b29
MainWindow 툴바 메뉴 중 [장치 노즐 연계] 삭제 및 [장치 생성], [노즐 생성] 추가 / CreateSymbolCommand 작성 후 장치, 노줄 생성에 연결
DTI_PID/DTI_PID/Commands/CreateSymbolCommand.py | ||
---|---|---|
1 |
import os.path |
|
2 |
import AbstractCommand |
|
3 |
try: |
|
4 |
from PyQt5.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR |
|
5 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QCursor |
|
6 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog |
|
7 |
except ImportError: |
|
8 |
try: |
|
9 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR |
|
10 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QCursor |
|
11 |
except ImportError: |
|
12 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
13 |
import sys, os |
|
14 |
from AppDocData import AppDocData |
|
15 |
import cv2 |
|
16 |
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) |
|
17 |
import QSymbolEditorDialog |
|
18 |
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\Shapes') |
|
19 |
from SymbolSvgItem import SymbolSvgItem |
|
20 | ||
21 |
class CreateSymbolCommand(AbstractCommand.AbstractCommand): |
|
22 |
def __init__(self, imageViewer, resultTreeWidget): |
|
23 |
super(CreateSymbolCommand, self).__init__(imageViewer) |
|
24 |
self.name = 'CreateSymbol' |
|
25 |
self.imageViewer.setCursor(QCursor(Qt.CrossCursor)) |
|
26 |
self.resultTreeWidget = resultTreeWidget |
|
27 |
|
|
28 |
''' |
|
29 |
@brief crop image by rectangle selected by user |
|
30 |
@history 2018.05.02 Jeongwoo Init self.offsetX and self.offsetY |
|
31 |
Add QtImageViewer.startPointChanged.emit |
|
32 |
''' |
|
33 |
def execute(self, param): |
|
34 |
event = param[1] |
|
35 |
scenePos = param[2] |
|
36 |
if 'mousePressEvent' == param[0] and event.button() == Qt.LeftButton: |
|
37 |
self.imageViewer.setDragMode(QGraphicsView.RubberBandDrag) |
|
38 |
self.imageViewer.leftMouseButtonPressed.emit(scenePos.x(), scenePos.y()) |
|
39 |
QGraphicsView.mousePressEvent(self.imageViewer, event) |
|
40 |
elif 'mouseReleaseEvent' == param[0] and event.button() == Qt.LeftButton: |
|
41 |
try: |
|
42 |
QGraphicsView.mouseReleaseEvent(self.imageViewer, event) |
|
43 |
viewBBox = self.imageViewer.zoomStack[-1] if len(self.imageViewer.zoomStack) else self.imageViewer.sceneRect() |
|
44 |
selectionBBox = self.imageViewer.scene.selectionArea().boundingRect().intersected(viewBBox) |
|
45 |
if selectionBBox.isValid(): |
|
46 |
croppedImage = self.imageViewer.image().copy(selectionBBox.toAlignedRect()) |
|
47 |
symbolEditorDialog = QSymbolEditorDialog.QSymbolEditorDialog(self.imageViewer, croppedImage, AppDocData.instance().getCurrentProject()) |
|
48 |
(isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
|
49 |
if isAccepted: |
|
50 |
if isImmediateInsert: |
|
51 |
svgPath = AppDocData.instance().getCurrentProject().getSvgFilePath() + "/" + newSym.getType() + "/" + newSym.getName() + ".svg" |
|
52 |
img = cv2.imread(AppDocData.instance().getCurrentProject().getImageFilePath() + "/" + newSym.getType() + "/" + newSym.getName() + ".png", 1) |
|
53 |
w, h = (0, 0) |
|
54 |
if len(img.shape[::-1]) == 2: |
|
55 |
w, h = img.shape[::-1] |
|
56 |
else: |
|
57 |
_chan, w, h = img.shape[::-1] |
|
58 |
svg = SymbolSvgItem(svgPath) |
|
59 |
svg.buildItem(newSym.getName(), newSym.getType(), 0, [selectionBBox.x()+offsetX, selectionBBox.y()+offsetY], [w, h], [float(x) for x in newSym.getOriginalPoint().split(',')], [(float(x.split(',')[0]), float(x.split(',')[1])) for x in newSym.getConnectionPoint().split('/')]) |
|
60 | ||
61 |
#### lambda param=svg : bind 'svg' object to lambda('param') |
|
62 |
#### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda |
|
63 |
svg.clicked.connect(lambda param=svg: self.resultTreeWidget.findItem(param)) |
|
64 |
svg.removed.connect(self.resultTreeWidget.itemRemoved) |
|
65 |
svg.addSvgItemToScene(self.imageViewer.scene) |
|
66 |
for connector in svg.connectors: |
|
67 |
self.imageViewer.scene.addItem(connector) |
|
68 | ||
69 |
finally: |
|
70 |
self.imageViewer.setDragMode(QGraphicsView.NoDrag) |
|
71 |
self.imageViewer.leftMouseButtonReleased.emit(scenePos.x(), scenePos.y()) |
|
72 |
pass |
|
73 |
self.isTreated = False |
|
74 | ||
75 |
def undo(self): |
|
76 |
pass |
|
77 | ||
78 |
def redo(self): |
|
79 |
pass |
DTI_PID/DTI_PID/DTI_PID_UI.py | ||
---|---|---|
108 | 108 |
icon2.addPixmap(QtGui.QPixmap(":/appPrefix/draw-line-icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) |
109 | 109 |
self.actionLine.setIcon(icon2) |
110 | 110 |
self.actionLine.setObjectName("actionLine") |
111 |
self.actionEqpNozzle = QtWidgets.QAction(MainWindow) |
|
112 |
self.actionEqpNozzle.setObjectName("actionEqpNozzle") |
|
113 | 111 |
self.actionValidate = QtWidgets.QAction(MainWindow) |
114 | 112 |
icon3 = QtGui.QIcon() |
115 | 113 |
icon3.addPixmap(QtGui.QPixmap(":/appPrefix/validation-icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) |
... | ... | |
126 | 124 |
self.actionLineRecognition.setObjectName("actionLineRecognition") |
127 | 125 |
self.actionGenerateOutput = QtWidgets.QAction(MainWindow) |
128 | 126 |
self.actionGenerateOutput.setObjectName("actionGenerateOutput") |
127 |
self.actionEquipment = QtWidgets.QAction(MainWindow) |
|
128 |
self.actionEquipment.setCheckable(True) |
|
129 |
self.actionEquipment.setObjectName("actionEquipment") |
|
130 |
self.actionNozzle = QtWidgets.QAction(MainWindow) |
|
131 |
self.actionNozzle.setCheckable(True) |
|
132 |
self.actionNozzle.setObjectName("actionNozzle") |
|
129 | 133 |
self.menu.addAction(self.actionOpen) |
130 | 134 |
self.menu.addAction(self.actionArea) |
131 | 135 |
self.menu.addAction(self.actionConfiguration) |
... | ... | |
136 | 140 |
self.toolBar.addAction(self.actionRecognition) |
137 | 141 |
self.toolBar.addAction(self.actionLineRecognition) |
138 | 142 |
self.toolBar.addSeparator() |
139 |
self.toolBar.addAction(self.actionEqpNozzle) |
|
143 |
self.toolBar.addAction(self.actionEquipment) |
|
144 |
self.toolBar.addAction(self.actionNozzle) |
|
140 | 145 |
self.toolBar.addAction(self.actionLine) |
141 | 146 |
self.toolBar.addAction(self.actionValidate) |
142 | 147 |
self.toolBar.addSeparator() |
... | ... | |
164 | 169 |
self.actionRecognition.setToolTip(_translate("MainWindow", "심볼,텍스트 인식")) |
165 | 170 |
self.actionLine.setText(_translate("MainWindow", "라인 생성")) |
166 | 171 |
self.actionLine.setToolTip(_translate("MainWindow", "라인 생성")) |
167 |
self.actionEqpNozzle.setText(_translate("MainWindow", "장치와 노즐 연계")) |
|
168 |
self.actionEqpNozzle.setToolTip(_translate("MainWindow", "장치와 노즐 연계")) |
|
169 | 172 |
self.actionValidate.setText(_translate("MainWindow", "검사")) |
170 | 173 |
self.actionValidate.setToolTip(_translate("MainWindow", "검사")) |
171 | 174 |
self.actionConfiguration.setText(_translate("MainWindow", "환경 설정")) |
... | ... | |
175 | 178 |
self.actionLineRecognition.setText(_translate("MainWindow", "라인 인식")) |
176 | 179 |
self.actionLineRecognition.setToolTip(_translate("MainWindow", "라인 인식")) |
177 | 180 |
self.actionGenerateOutput.setText(_translate("MainWindow", "변환")) |
181 |
self.actionEquipment.setText(_translate("MainWindow", "장치 생성")) |
|
182 |
self.actionEquipment.setToolTip(_translate("MainWindow", "장치 생성")) |
|
183 |
self.actionNozzle.setText(_translate("MainWindow", "노즐 생성")) |
|
184 |
self.actionNozzle.setToolTip(_translate("MainWindow", "노즐 생성")) |
|
178 | 185 | |
179 | 186 | |
180 | 187 |
if __name__ == "__main__": |
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
19 | 19 |
import CreateCommand |
20 | 20 |
import CropCommand |
21 | 21 |
import AreaOcrCommand |
22 |
import CreateSymbolCommand |
|
22 | 23 | |
23 | 24 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes') |
24 | 25 |
import QGraphicsPolylineItem |
... | ... | |
119 | 120 |
# connect signals and slots |
120 | 121 |
self.actionClose.triggered.connect(self.close) |
121 | 122 |
self.actionOpen.triggered.connect(self.openImageDrawing) |
122 |
self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle) |
|
123 |
#self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle)
|
|
123 | 124 |
self.actionLine.triggered.connect(self.createLine) |
124 | 125 |
self.actionRecognition.triggered.connect(self.recognize) |
125 | 126 |
self.actionLineRecognition.triggered.connect(self.recognizeLine) |
... | ... | |
128 | 129 |
self.actionOCR.triggered.connect(self.areaOcr) |
129 | 130 |
self.actionGenerateOutput.triggered.connect(self.generateOutput) |
130 | 131 |
self.pushButtonCreateSymbol.clicked.connect(self.createSymbol) |
132 |
self.actionEquipment.triggered.connect(self.createEquipment) |
|
133 |
self.actionNozzle.triggered.connect(self.createNozzle) |
|
131 | 134 |
self.graphicsView.scene.changed.connect(lambda: self.resultTreeWidget.sceneChanged(self.graphicsView.scene.items())) |
132 | 135 | |
133 | 136 |
''' |
137 |
@brief Create Equipment |
|
138 |
@author Jeongwoo |
|
139 |
@date 18.05.03 |
|
140 |
''' |
|
141 |
def createEquipment(self): |
|
142 |
if not self.graphicsView.hasImage(): |
|
143 |
self.showImageSelectionMessageBox() |
|
144 |
return |
|
145 |
if self.actionEquipment.isChecked(): |
|
146 |
self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget) |
|
147 |
else: |
|
148 |
self.graphicsView.useDefaultCommand() |
|
149 | ||
150 | ||
151 |
''' |
|
152 |
@brief Create Nozzle |
|
153 |
@author Jeongwoo |
|
154 |
@date 18.05.03 |
|
155 |
''' |
|
156 |
def createNozzle(self): |
|
157 |
if not self.graphicsView.hasImage(): |
|
158 |
self.showImageSelectionMessageBox() |
|
159 |
return |
|
160 |
if self.actionNozzle.isChecked(): |
|
161 |
self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget) |
|
162 |
else: |
|
163 |
self.graphicsView.useDefaultCommand() |
|
164 | ||
165 |
''' |
|
134 | 166 |
@brief Area OCR |
135 | 167 |
@author Jeongwoo |
136 | 168 |
@date 18.04.18 |
... | ... | |
318 | 350 |
for connector in svg.connectors: |
319 | 351 |
self.graphicsView.scene.addItem(connector) |
320 | 352 | |
321 |
''' |
|
322 |
@brief connect equipment and nozzle |
|
323 |
''' |
|
324 |
def connectEqpNozzle(self): |
|
325 |
self.graphicsView.command = None |
|
353 |
#'''
|
|
354 |
# @brief connect equipment and nozzle
|
|
355 |
#'''
|
|
356 |
#def connectEqpNozzle(self):
|
|
357 |
# self.graphicsView.command = None
|
|
326 | 358 | |
327 | 359 |
''' |
328 | 360 |
@brief create a line |
DTI_PID/DTI_PID/UI/DTI__PID.ui | ||
---|---|---|
80 | 80 |
<addaction name="actionRecognition"/> |
81 | 81 |
<addaction name="actionLineRecognition"/> |
82 | 82 |
<addaction name="separator"/> |
83 |
<addaction name="actionEqpNozzle"/> |
|
83 |
<addaction name="actionEquipment"/> |
|
84 |
<addaction name="actionNozzle"/> |
|
84 | 85 |
<addaction name="actionLine"/> |
85 | 86 |
<addaction name="actionValidate"/> |
86 | 87 |
<addaction name="separator"/> |
... | ... | |
208 | 209 |
<string>라인 생성</string> |
209 | 210 |
</property> |
210 | 211 |
</action> |
211 |
<action name="actionEqpNozzle"> |
|
212 |
<property name="text"> |
|
213 |
<string>장치와 노즐 연계</string> |
|
214 |
</property> |
|
215 |
<property name="toolTip"> |
|
216 |
<string>장치와 노즐 연계</string> |
|
217 |
</property> |
|
218 |
</action> |
|
219 | 212 |
<action name="actionValidate"> |
220 | 213 |
<property name="icon"> |
221 | 214 |
<iconset> |
... | ... | |
262 | 255 |
<string>변환</string> |
263 | 256 |
</property> |
264 | 257 |
</action> |
258 |
<action name="actionEquipment"> |
|
259 |
<property name="checkable"> |
|
260 |
<bool>true</bool> |
|
261 |
</property> |
|
262 |
<property name="text"> |
|
263 |
<string>장치 생성</string> |
|
264 |
</property> |
|
265 |
<property name="toolTip"> |
|
266 |
<string>장치 생성</string> |
|
267 |
</property> |
|
268 |
</action> |
|
269 |
<action name="actionNozzle"> |
|
270 |
<property name="checkable"> |
|
271 |
<bool>true</bool> |
|
272 |
</property> |
|
273 |
<property name="text"> |
|
274 |
<string>노즐 생성</string> |
|
275 |
</property> |
|
276 |
<property name="toolTip"> |
|
277 |
<string>노즐 생성</string> |
|
278 |
</property> |
|
279 |
</action> |
|
265 | 280 |
</widget> |
266 | 281 |
<resources/> |
267 | 282 |
<connections/> |
내보내기 Unified diff