개정판 47bd6b4e
QRecognitionDialog 에 Line 인식 추가 및 그에 따른 Signal 등의 구조 변경
DTI_PID/DTI_PID/DTI_PID.py | ||
---|---|---|
501 | 501 |
|
502 | 502 |
threadLock.acquire() |
503 | 503 |
srcName = os.path.splitext(os.path.basename(mainRes))[0] |
504 |
listWidget.addItem('Finish symbol : ' + os.path.basename(symbolPath.replace('.png', '')) + ' - (' + str(foundSymbolCount) + ')')
|
|
504 |
listWidget.addItem('Finish Symbol : ' + os.path.basename(symbolPath.replace('.png', '')) + ' - (' + str(foundSymbolCount) + ')')
|
|
505 | 505 |
threadLock.release() |
506 | 506 |
|
507 | 507 |
''' |
... | ... | |
799 | 799 |
searchedSymbolList = [] |
800 | 800 |
textInfoList = [] |
801 | 801 |
|
802 |
start = timeit.default_timer() |
|
802 |
#start = timeit.default_timer()
|
|
803 | 803 |
|
804 | 804 |
initMainSrc(mainRes) |
805 | 805 |
|
... | ... | |
863 | 863 |
|
864 | 864 |
listWidget.addItem("Searched symbol count : " + str(len(searchedSymbolList))) |
865 | 865 |
|
866 |
stop = timeit.default_timer() |
|
867 |
seconds = stop - start |
|
866 |
#stop = timeit.default_timer()
|
|
867 |
#seconds = stop - start
|
|
868 | 868 |
|
869 |
listWidget.addItem("\nRunning Time : " + str(seconds / 60) + "min\n") |
|
869 |
#listWidget.addItem("\nRunning Time : " + str(seconds / 60) + "min\n")
|
|
870 | 870 |
except Exception as ex: |
871 | 871 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
872 | 872 |
|
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
437 | 437 |
@history 2018.04.16 humkyung execute line no tracing |
438 | 438 |
2018.05.02 Jeongwoo Show MessageBox when imageviewer doesn't have image |
439 | 439 |
2018.05.25 Jeongwoo Add parameter on QRecognitionDialog.__init__() and Move thread to QRecognitionDialog |
440 |
Remove codes below if self.dlg.isAccepted == True |
|
440 | 441 |
''' |
441 | 442 |
def recognize(self, MainWindow): |
442 | 443 |
from QRecognitionDialog import QRecognitionDialog |
... | ... | |
446 | 447 |
return |
447 | 448 |
|
448 | 449 |
try: |
449 |
self.dlg = QRecognitionDialog(self, self.path) |
|
450 |
self.dlg = QRecognitionDialog(self.graphicsView, self.path) |
|
451 |
self.dlg.svgItemClicked.connect(self.svgItemClicked) |
|
452 |
self.dlg.itemRemoved.connect(self.itemRemoved) |
|
450 | 453 |
self.dlg.exec_() |
451 | 454 |
if self.dlg.isAccepted == True: |
452 |
if self.dlg.xmlPath is not None: |
|
453 |
self.loadRecognitionResult(self.dlg.xmlPath[0]) |
|
455 |
'''DO NOTHING''' |
|
456 |
#if self.dlg.xmlPath is not None: |
|
457 |
# self.loadRecognitionResult(self.dlg.xmlPath[0]) |
|
454 | 458 |
except Exception as ex: |
455 | 459 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
456 | 460 |
|
457 | 461 |
''' |
458 |
@brief remove small objects from given image
|
|
459 |
@author humkyung
|
|
460 |
@date 2018.04.26
|
|
462 |
@brief |
|
463 |
@date 2018.05.25
|
|
464 |
@author Jeongwoo
|
|
461 | 465 |
''' |
462 |
def removeSmallObjects(self, image): |
|
463 |
try: |
|
464 |
docData = AppDocData.instance() |
|
465 |
configs = docData.getConfigs('Small Object Size', 'Min Area') |
|
466 |
minArea = int(configs[0].value) if 1 == len(configs) else 20 |
|
467 |
configs = docData.getConfigs('Small Object Size', 'Max Area') |
|
468 |
maxArea = int(configs[0].value) if 1 == len(configs) else 50 |
|
469 |
|
|
470 |
#path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), 'before_contours.png') |
|
471 |
#cv2.imwrite(path, image) |
|
472 |
|
|
473 |
_,contours,_ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE); |
|
474 |
selectedContours=[] |
|
475 |
for contour in contours: |
|
476 |
#if cv2.isContourConvex(contour): |
|
477 |
#approx = cv2.approxPolyDP(contour, 0.2*cv2.arcLength(contour, True), True) |
|
478 |
area = cv2.contourArea(contour) |
|
479 |
if area > minArea and area < maxArea: selectedContours.append(contour) |
|
480 |
contourImage = cv2.drawContours(image, selectedContours, -1, (255,255,255), -1); |
|
481 |
#path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), 'contours.png') |
|
482 |
#cv2.imwrite(path, contourImage) |
|
483 |
except Exception as ex: |
|
484 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
485 |
|
|
486 |
return contourImage |
|
487 |
|
|
466 |
def svgItemClicked(self, svgItem): |
|
467 |
self.resultTreeWidget.findItem(svgItem) |
|
468 |
|
|
469 |
''' |
|
470 |
@brief |
|
471 |
@date 2018.05.25 |
|
472 |
@author Jeongwoo |
|
473 |
''' |
|
474 |
def itemRemoved(self, item): |
|
475 |
self.resultTreeWidget.itemRemoved(item) |
|
476 |
|
|
488 | 477 |
''' |
489 | 478 |
@brief recognize line |
490 | 479 |
@author humkyung |
... | ... | |
493 | 482 |
TextItem type changed (QEngineeringTextItem → QEngineeringLineNoTextItem) |
494 | 483 |
humkyung 2018.04.26 remove small objects before recognizing line |
495 | 484 |
Jeongwoo 2018.05.02 Show MessageBox when imageviewer doesn't have image |
485 |
Jeongwoo 2018.05.25 Move codes about LineDetector |
|
496 | 486 |
''' |
497 | 487 |
def recognizeLine(self, MainWindow): |
498 |
from LineDetector import LineDetector |
|
499 | 488 |
from LineNoTracer import LineNoTracer |
500 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
|
501 | 489 |
|
502 | 490 |
if not self.graphicsView.hasImage(): |
503 | 491 |
self.showImageSelectionMessageBox() |
504 | 492 |
return |
505 | 493 |
|
506 | 494 |
try: |
507 |
#remove already existing line and flow arrow item |
|
508 |
items = [item for item in self.graphicsView.scene.items() if (type(item) is QEngineeringLineItem) or (type(item) is QEngineeringFlowArrowItem)] |
|
509 |
for item in items: |
|
510 |
self.graphicsView.scene.removeItem(item) |
|
511 |
#up to here |
|
512 |
|
|
513 |
# detect line |
|
514 |
connectedLines = [] |
|
515 |
|
|
516 |
area = AppDocData.instance().getArea('Drawing') |
|
517 |
area.img = self.removeSmallObjects(area.img) |
|
518 |
detector = LineDetector(area.img) |
|
519 |
|
|
520 | 495 |
symbols = [] |
496 |
lines = [] |
|
497 |
lineNos = [] |
|
521 | 498 |
for item in self.graphicsView.scene.items(): |
522 | 499 |
if issubclass(type(item), SymbolSvgItem): |
523 | 500 |
symbols.append(item) |
524 |
res = detector.detectConnectedLine(item, round(area.x), round(area.y)) |
|
525 |
if res is not None: |
|
526 |
for line in res: connectedLines.append(line) |
|
527 |
|
|
528 |
texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
|
529 |
for symbol in symbols: |
|
530 |
symbol.connectAttribute(texts) |
|
531 |
|
|
532 |
lineNos = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineNoTextItem] |
|
533 |
|
|
534 |
if len(connectedLines) > 1: |
|
535 |
detector.mergeLines(connectedLines, toler=20) |
|
536 |
# connect line to symbol |
|
537 |
try: |
|
538 |
for line in connectedLines: |
|
539 |
matches = [symbol for symbol in symbols if symbol.isConnectable(line, (round(area.x), round(area.y)), toler=20)] |
|
540 |
for symbol in matches: |
|
541 |
detector.connectLineToSymbol(line, (round(area.x), round(area.y)), symbol) |
|
542 |
except Exception as ex: |
|
543 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
544 |
# up to here |
|
545 |
|
|
546 |
# connect line to line |
|
547 |
try: |
|
548 |
for line in connectedLines[:]: |
|
549 |
matches = [it for it in connectedLines if (line != it) and (not detector.isParallel(line, it))] |
|
550 |
for match in matches: |
|
551 |
detector.connectLineToLine(match, line) |
|
552 |
except Exception as ex: |
|
553 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
554 |
# up to here |
|
555 |
|
|
556 |
lines = [] |
|
557 |
for pts in connectedLines: |
|
558 |
processLine = QEngineeringLineItem() |
|
559 |
lines.append(processLine) |
|
560 |
for pt in pts: |
|
561 |
processLine._pol.append(QPointF(pt[0] + round(area.x), pt[1] + round(area.y))) |
|
562 |
processLine.buildItem() |
|
563 |
self.graphicsView.scene.addItem(processLine) |
|
501 |
elif type(item) is QEngineeringLineNoTextItem: |
|
502 |
lineNos.append(item) |
|
503 |
elif type(item) is QEngineeringLineItem: |
|
504 |
lines.append(item) |
|
564 | 505 |
|
565 | 506 |
# trace line no |
566 | 507 |
tracer = LineNoTracer(symbols, lines, lineNos) |
DTI_PID/DTI_PID/QRecognitionDialog.py | ||
---|---|---|
3 | 3 |
from PyQt5.QtGui import * |
4 | 4 |
from PyQt5.QtWidgets import * |
5 | 5 |
import Recognition_UI |
6 |
import sys |
|
7 |
import os |
|
8 |
import cv2 |
|
9 |
from AppDocData import AppDocData |
|
10 |
from LineDetector import LineDetector |
|
11 |
from QEngineeringLineItem import QEngineeringLineItem |
|
12 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
13 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
|
14 |
from SymbolSvgItem import SymbolSvgItem |
|
15 |
from QEngineeringTextItem import QEngineeringTextItem |
|
6 | 16 |
|
17 |
''' |
|
18 |
@history 2018.05.25 Jeongwoo Add pyqtSignal(recognizeLine, loadRecognitionResult) |
|
19 |
''' |
|
7 | 20 |
class Worker(QObject): |
8 | 21 |
from PyQt5.QtCore import QThread |
9 | 22 |
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout |
10 | 23 |
import sys |
11 |
from DTI_PID import executeRecognition
|
|
24 |
import timeit
|
|
12 | 25 |
|
13 | 26 |
finished = pyqtSignal() |
14 | 27 |
intReady = pyqtSignal(int) |
28 |
recognizeLine = pyqtSignal() |
|
29 |
loadRecognitionResult = pyqtSignal(str) |
|
15 | 30 |
|
31 |
''' |
|
32 |
@history 2018.05.25 Jeongwoo Add if-statements by isSymbolTextChecked and isLineChecked variable |
|
33 |
''' |
|
16 | 34 |
#pyqtSlot() |
17 | 35 |
def procCounter(self, isSymbolTextChecked, isLineChecked): # A slot takes no params |
18 | 36 |
from DTI_PID import executeRecognition |
37 |
import timeit |
|
19 | 38 |
|
20 | 39 |
try: |
40 |
start = timeit.default_timer() |
|
21 | 41 |
self.xmlPath = None |
22 | 42 |
if isSymbolTextChecked: |
23 | 43 |
self.xmlPath = executeRecognition(self.path, self.listWidget) |
44 |
if self.xmlPath is not None and len(self.xmlPath) > 0: |
|
45 |
self.loadRecognitionResult.emit(self.xmlPath[0]) |
|
46 |
if isLineChecked: |
|
47 |
self.recognizeLine.emit() |
|
24 | 48 |
self.finished.emit() |
25 | 49 |
except Exception as ex: |
26 | 50 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
51 |
finally: |
|
52 |
stop = timeit.default_timer() |
|
53 |
seconds = stop - start |
|
54 |
self.listWidget.addItem("\nRunning Time : " + str(seconds / 60) + "min\n") |
|
27 | 55 |
|
56 |
''' |
|
57 |
@history 2018.05.25 Jeongwoo Add pyqtSignal(svgItemClicked, itemRemoved) |
|
58 |
''' |
|
28 | 59 |
class QRecognitionDialog(QDialog): |
60 |
svgItemClicked = pyqtSignal(SymbolSvgItem) |
|
61 |
itemRemoved = pyqtSignal(QGraphicsItem) |
|
62 |
|
|
29 | 63 |
''' |
30 | 64 |
@history 2018.05.25 Jeongwoo Add parameter and initialize / Connect recognizeButton signal and slot |
31 | 65 |
''' |
32 |
def __init__(self, parent, path):
|
|
33 |
QDialog.__init__(self, parent)
|
|
66 |
def __init__(self, graphicsView, path):
|
|
67 |
QDialog.__init__(self, graphicsView)
|
|
34 | 68 |
|
69 |
self.graphicsView = graphicsView |
|
35 | 70 |
self.path = path |
36 | 71 |
self.xmlPath = None |
37 | 72 |
self.ui = Recognition_UI.Ui_Recognition() |
... | ... | |
80 | 115 |
|
81 | 116 |
# 4 - Connect Worker Signals to the Thread slots |
82 | 117 |
self.obj.finished.connect(self.thread.quit) |
118 |
self.obj.recognizeLine.connect(self.recognizeLine) |
|
119 |
self.obj.loadRecognitionResult.connect(self.loadRecognitionResult) |
|
83 | 120 |
|
84 | 121 |
# 5 - Connect Thread started signal to Worker operational slot method |
85 | 122 |
self.thread.started.connect(lambda : self.obj.procCounter(self.ui.symbolTextCheckBox.isChecked(), self.ui.lineCheckBox.isChecked())) |
... | ... | |
96 | 133 |
''' |
97 | 134 |
def dlgExit(self): |
98 | 135 |
self.xmlPath = self.obj.xmlPath |
99 |
self.ui.buttonBox.setEnabled(True) |
|
136 |
self.ui.buttonBox.setEnabled(True) |
|
137 |
|
|
138 |
''' |
|
139 |
@brief remove small objects from given image |
|
140 |
@author humkyung |
|
141 |
@date 2018.04.26 |
|
142 |
@history 2018.05.25 Jeongwoo Moved from MainWindow |
|
143 |
''' |
|
144 |
def removeSmallObjects(self, image): |
|
145 |
try: |
|
146 |
docData = AppDocData.instance() |
|
147 |
configs = docData.getConfigs('Small Object Size', 'Min Area') |
|
148 |
minArea = int(configs[0].value) if 1 == len(configs) else 20 |
|
149 |
configs = docData.getConfigs('Small Object Size', 'Max Area') |
|
150 |
maxArea = int(configs[0].value) if 1 == len(configs) else 50 |
|
151 |
|
|
152 |
#path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), 'before_contours.png') |
|
153 |
#cv2.imwrite(path, image) |
|
154 |
|
|
155 |
_,contours,_ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE); |
|
156 |
selectedContours=[] |
|
157 |
for contour in contours: |
|
158 |
#if cv2.isContourConvex(contour): |
|
159 |
#approx = cv2.approxPolyDP(contour, 0.2*cv2.arcLength(contour, True), True) |
|
160 |
area = cv2.contourArea(contour) |
|
161 |
if area > minArea and area < maxArea: selectedContours.append(contour) |
|
162 |
contourImage = cv2.drawContours(image, selectedContours, -1, (255,255,255), -1); |
|
163 |
#path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), 'contours.png') |
|
164 |
#cv2.imwrite(path, contourImage) |
|
165 |
except Exception as ex: |
|
166 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
167 |
|
|
168 |
return contourImage |
|
169 |
|
|
170 |
''' |
|
171 |
@history 2018.05.25 Jeongwoo Moved from MainWindow |
|
172 |
SvgItem and TextItem Connect with method in this class |
|
173 |
''' |
|
174 |
def loadRecognitionResult(self, xmlPath): |
|
175 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse |
|
176 |
from TextItemFactory import TextItemFactory |
|
177 |
|
|
178 |
try: |
|
179 |
project = AppDocData.instance().getCurrentProject() |
|
180 |
|
|
181 |
xml = parse(xmlPath) |
|
182 |
root = xml.getroot(); |
|
183 |
for symbol in root.iter('SYMBOL'): |
|
184 |
pt = [float(x) for x in symbol.find('STARTPOINT').text.split(',')] |
|
185 |
size = [float(x) for x in symbol.find('SIZE').text.split(',')] |
|
186 |
name = symbol.find('NAME').text |
|
187 |
angle = float(symbol.find('ANGLE').text) |
|
188 |
type = symbol.find('TYPE').text |
|
189 |
origin = [float(x) for x in symbol.find('ORIGINALPOINT').text.split(',')] |
|
190 |
connPts = [] |
|
191 |
if symbol.find('CONNECTIONPOINT').text is not None: |
|
192 |
connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) for x in symbol.find('CONNECTIONPOINT').text.split('/')] |
|
193 |
|
|
194 |
svgFilePath = os.path.join(project.getSvgFilePath(), type, name + '.svg') |
|
195 |
if os.path.isfile(svgFilePath): |
|
196 |
svg = SymbolSvgItem.createItem(type, svgFilePath) |
|
197 |
svg.buildItem(name, type, angle, pt, size, origin, connPts) |
|
198 |
|
|
199 |
#### lambda param=svg : bind 'svg' object to lambda('param') |
|
200 |
#### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda |
|
201 |
svg.clicked.connect(lambda param=svg: self.svgItemClickedEvent(param)) |
|
202 |
svg.removed.connect(lambda param=svg: self.itemRemovedEvent(param)) |
|
203 |
svg.addSvgItemToScene(self.graphicsView.scene) |
|
204 |
for connector in svg.connectors: |
|
205 |
self.graphicsView.scene.addItem(connector) |
|
206 |
else: |
|
207 |
item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1]) |
|
208 |
item.isSymbol = True |
|
209 |
item.angle = angle |
|
210 |
item.setPen(QPen(Qt.red, 20, Qt.SolidLine)) |
|
211 |
self.graphicsView.scene.addItem(item) |
|
212 |
|
|
213 |
docData = AppDocData.instance() |
|
214 |
configs = docData.getConfigs('Line No', 'Delimiter') |
|
215 |
delimiter = configs[0].value if 1 == len(configs) else '-' |
|
216 |
lineNoconfigs = docData.getConfigs('Line No', 'Configuration') |
|
217 |
# parse texts |
|
218 |
for text in root.iter('TEXTINFO'): |
|
219 |
x = float(text.find('X').text) if text.find('X') is not None else 0 |
|
220 |
y = float(text.find('Y').text) if text.find('Y') is not None else 0 |
|
221 |
width = float(text.find('WIDTH').text) if text.find('WIDTH') is not None else 0 |
|
222 |
height = float(text.find('HEIGHT').text) if text.find('HEIGHT') is not None else 0 |
|
223 |
angle = float(text.find('ANGLE').text) if text.find('ANGLE') is not None else 0 |
|
224 |
text = text.find('TEXT').text |
|
225 |
item = TextItemFactory.instance().createTextItem(text, delimiter, lineNoconfigs) |
|
226 |
if item is not None: |
|
227 |
item.loc = (x, y) |
|
228 |
item.size = (width, height) |
|
229 |
item.angle = angle |
|
230 |
item.setPlainText(text) |
|
231 |
item.removed.connect(lambda param=item: self.itemRemovedEvent(param)) |
|
232 |
item.addTextItemToScene(self.graphicsView.scene) |
|
233 |
|
|
234 |
# parse notes |
|
235 |
for note in root.iter('NOTE'): |
|
236 |
x = float(note.find('X').text) if note.find('X') is not None else 0 |
|
237 |
y = float(note.find('Y').text) if note.find('Y') is not None else 0 |
|
238 |
width = float(note.find('WIDTH').text) if note.find('WIDTH') is not None else 0 |
|
239 |
height = float(note.find('HEIGHT').text) if note.find('HEIGHT') is not None else 0 |
|
240 |
angle = float(note.find('ANGLE').text) if note.find('ANGLE') is not None else 0 |
|
241 |
text = note.find('TEXT').text |
|
242 |
item = TextItemFactory.instance().createTextItem(text) |
|
243 |
item.loc = (x, y) |
|
244 |
item.size = (width, height) |
|
245 |
item.angle = angle |
|
246 |
item.setPlainText(text) |
|
247 |
item.addTextItemToScene(self.graphicsView.scene) |
|
248 |
|
|
249 |
#self.graphicsView.scene.addItem(item) |
|
250 |
# up to here |
|
251 |
except Exception as ex: |
|
252 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
253 |
|
|
254 |
''' |
|
255 |
@history 2018.05.25 Jeongwoo Moved from MainWindow |
|
256 |
''' |
|
257 |
def recognizeLine(self): |
|
258 |
try: |
|
259 |
#remove already existing line and flow arrow item |
|
260 |
items = [item for item in self.graphicsView.scene.items() if (type(item) is QEngineeringLineItem) or (type(item) is QEngineeringFlowArrowItem)] |
|
261 |
for item in items: |
|
262 |
self.graphicsView.scene.removeItem(item) |
|
263 |
#up to here |
|
264 |
|
|
265 |
# detect line |
|
266 |
connectedLines = [] |
|
267 |
|
|
268 |
area = AppDocData.instance().getArea('Drawing') |
|
269 |
area.img = self.removeSmallObjects(area.img) |
|
270 |
detector = LineDetector(area.img) |
|
271 |
|
|
272 |
symbols = [] |
|
273 |
for item in self.graphicsView.scene.items(): |
|
274 |
if issubclass(type(item), SymbolSvgItem): |
|
275 |
symbols.append(item) |
|
276 |
res = detector.detectConnectedLine(item, round(area.x), round(area.y)) |
|
277 |
if res is not None: |
|
278 |
for line in res: connectedLines.append(line) |
|
279 |
|
|
280 |
texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
|
281 |
for symbol in symbols: |
|
282 |
symbol.connectAttribute(texts) |
|
283 |
|
|
284 |
lineNos = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineNoTextItem] |
|
285 |
|
|
286 |
if len(connectedLines) > 1: |
|
287 |
detector.mergeLines(connectedLines, toler=20) |
|
288 |
# connect line to symbol |
|
289 |
try: |
|
290 |
for line in connectedLines: |
|
291 |
matches = [symbol for symbol in symbols if symbol.isConnectable(line, (round(area.x), round(area.y)), toler=20)] |
|
292 |
for symbol in matches: |
|
293 |
detector.connectLineToSymbol(line, (round(area.x), round(area.y)), symbol) |
|
294 |
except Exception as ex: |
|
295 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
296 |
# up to here |
|
297 |
|
|
298 |
# connect line to line |
|
299 |
try: |
|
300 |
for line in connectedLines[:]: |
|
301 |
matches = [it for it in connectedLines if (line != it) and (not detector.isParallel(line, it))] |
|
302 |
for match in matches: |
|
303 |
detector.connectLineToLine(match, line) |
|
304 |
except Exception as ex: |
|
305 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
306 |
# up to here |
|
307 |
|
|
308 |
lines = [] |
|
309 |
for pts in connectedLines: |
|
310 |
processLine = QEngineeringLineItem() |
|
311 |
lines.append(processLine) |
|
312 |
for pt in pts: |
|
313 |
processLine._pol.append(QPointF(pt[0] + round(area.x), pt[1] + round(area.y))) |
|
314 |
processLine.buildItem() |
|
315 |
self.graphicsView.scene.addItem(processLine) |
|
316 |
except Exception as ex: |
|
317 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
318 |
finally: |
|
319 |
self.ui.listWidget.addItem('Finish Line searching') |
|
320 |
|
|
321 |
''' |
|
322 |
@brief Emit svgItem to slot on MainWindow |
|
323 |
@date 2018.05.25 |
|
324 |
@author Jeongwoo |
|
325 |
''' |
|
326 |
def svgItemClickedEvent(self, svgItem): |
|
327 |
self.svgItemClicked.emit(svgItem) |
|
328 |
|
|
329 |
''' |
|
330 |
@brief Emit svgItem to slot on MainWindow |
|
331 |
@date 2018.05.25 |
|
332 |
@author Jeongwoo |
|
333 |
''' |
|
334 |
def itemRemovedEvent(self, item): |
|
335 |
self.itemRemoved.emit(item) |
DTI_PID/DTI_PID/Shapes/QEngineeringLineItem.py | ||
---|---|---|
24 | 24 |
2018.05.15 Jeongwoo Change method to call parent's __init__ |
25 | 25 |
''' |
26 | 26 |
def __init__(self, parent=None): |
27 |
super(QEngineeringLineItem, self).__init__() |
|
28 |
#QGraphicsPolylineItem.__init__(self, parent)
|
|
27 |
#super(QEngineeringLineItem, self).__init__()
|
|
28 |
QGraphicsPolylineItem.__init__(self, parent) |
|
29 | 29 |
|
30 | 30 |
self.conns = [None, None] |
31 | 31 |
self._owner = None |
DTI_PID/DTI_PID/Shapes/QGraphicsPolylineItem.py | ||
---|---|---|
16 | 16 |
''' |
17 | 17 |
@history 2018.05.11 Jeongwoo Declare variable self.pen |
18 | 18 |
2018.05.15 Jeongwoo Change method to call parent's __init__ |
19 |
2018.05.25 Jeongwoo Change self.pen's default color (red → blue) |
|
19 | 20 |
''' |
20 | 21 |
def __init__(self, parent=None): |
21 | 22 |
import uuid |
... | ... | |
31 | 32 |
self._pt = None |
32 | 33 |
self._pol = QPolygonF() |
33 | 34 |
self._path = None |
34 |
self.pen = QPen(Qt.red, 4, Qt.SolidLine) # default pen
|
|
35 |
self.pen = QPen(Qt.blue, 4, Qt.SolidLine) # default pen
|
|
35 | 36 |
self.setPen(self.pen) |
36 | 37 |
except Exception as ex: |
37 | 38 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
내보내기 Unified diff