프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / DTI_PID / DTI_PID / MainWindow.py @ d9cbc4d3

이력 | 보기 | 이력해설 | 다운로드 (30.5 KB)

1
# coding: utf-8
2

    
3
import sys
4
import os
5
import cv2
6

    
7
from PyQt5.QtCore import *
8
from PyQt5.QtGui import *
9
from PyQt5.QtWidgets import *
10
from PyQt5.QtSvg import *
11

    
12
from PIL import Image
13

    
14
import DTI_PID_UI
15
import QtImageViewer
16
from SingletonInstance import SingletonInstane
17

    
18
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
19
import CreateCommand
20
import CropCommand
21
import AreaOcrCommand
22
import CreateSymbolCommand
23

    
24
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes')
25
import QGraphicsPolylineItem
26
from QEngineeringLineItem import QEngineeringLineItem
27
from SymbolSvgItem import SymbolSvgItem
28
from QGraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
29
from QEngineeringTextItem import QEngineeringTextItem
30
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
31
from QEngineeringNoteItem import QEngineeringNoteItem
32
from QEngineeringSizeTextItem import QEngineeringSizeTextItem
33
from AppDocData import AppDocData
34
import QDirTreeWidget, QPropertyTableWidget
35
import QSymbolEditorDialog
36
import QResultTreeWidget
37
import QResultPropertyTableWidget
38
from TextItemFactory import TextItemFactory
39

    
40
class Worker(QObject):
41
    from PyQt5.QtCore import QThread
42
    from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout
43
    import sys
44
    from DTI_PID import executeRecognition
45

    
46
    finished = pyqtSignal()
47
    intReady = pyqtSignal(int)
48

    
49
    #pyqtSlot()
50
    def procCounter(self): # A slot takes no params
51
        from DTI_PID import executeRecognition
52

    
53
        try:
54
            self.xmlPath = executeRecognition(self.path, self.listWidget)
55
            self.finished.emit()
56
        except Exception as ex:
57
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
58

    
59
class MainWindow(QMainWindow, DTI_PID_UI.Ui_MainWindow, SingletonInstane):
60
    '''
61
        @brief      initialize
62
        @author 
63
        @date   
64
        @history    humkyung 2018.04.12 add splitter widget
65
                    Jeongwoo 2018.04.27 Add Signal/Slot Connection 'noteNoSingleClicked'
66
    '''
67
    def __init__(self):
68
        super(self.__class__, self).__init__()
69
        self.setupUi(self)
70

    
71
        project = AppDocData.instance().getCurrentProject()
72
        _translate = QCoreApplication.translate
73
        self.setWindowTitle(_translate("Digital P&ID - {}".format(project.name), "Digital P&ID - {}".format(project.name)))
74

    
75
        self.lineComboBox = QComboBox(self.toolBar)
76
        self.lineComboBox.addItem('Primary Line')
77
        self.lineComboBox.addItem('Secondary Line')
78
        #self.lineComboBox.addItem('Utility Line')
79
        self.toolBar.insertWidget(self.actionValidate, self.lineComboBox)
80
        self.toolBar.insertSeparator(self.actionValidate)
81
        self.graphicsView = QtImageViewer.QtImageViewer()
82
        self.graphicsView.setParent(self.centralwidget)
83
        self.graphicsView.useDefaultCommand() ##### USE DEFAULT COMMAND
84

    
85
        self.verticalLayout.addWidget(self.graphicsView)
86

    
87
        # Add Custom TreeWidget
88
        self.dirTreeWidget = QDirTreeWidget.QDirTreeWidget()
89
        self.dirTreeWidget.header().hide()
90
        self.symbolTabVerticalLayout.addWidget(self.dirTreeWidget)
91

    
92
        # Add Custom Property TableWidget
93
        self.propertyTableWidget = QPropertyTableWidget.QPropertyTableWidget()
94
        self.symbolTabVerticalLayout.addWidget(self.propertyTableWidget)
95
        self.dirTreeWidget.singleClicked.connect(self.propertyTableWidget.getClickedSymbol)
96
        # add splitter widget
97
        splitter = QSplitter(Qt.Vertical)
98
        splitter.addWidget(self.dirTreeWidget)
99
        splitter.addWidget(self.propertyTableWidget)
100
        self.symbolTabVerticalLayout.addWidget(splitter)
101
        # up to here
102

    
103
        # Add Custom Result Tree Widget (Symbol Explorer)
104
        self.resultTreeWidget = QResultTreeWidget.QResultTreeWidget(self.graphicsView)
105
        self.resultTreeWidget.header().hide()
106
        self.symbolExplorerVerticalLayout.addWidget(self.resultTreeWidget)
107

    
108
        # Add Empty Widget
109
        self.resultPropertyTableWidget = QResultPropertyTableWidget.QResultPropertyTableWidget()
110
        self.symbolExplorerVerticalLayout.addWidget(self.resultPropertyTableWidget)
111
        self.resultTreeWidget.singleClicked.connect(self.resultPropertyTableWidget.getClickedSymbol)
112
        self.resultTreeWidget.noteNoSingleClicked.connect(self.resultPropertyTableWidget.getClickedNote)
113
        # add splitter widget
114
        splitter = QSplitter(Qt.Vertical)
115
        splitter.addWidget(self.resultTreeWidget)
116
        splitter.addWidget(self.resultPropertyTableWidget)
117
        self.symbolExplorerVerticalLayout.addWidget(splitter)
118
        # up to here
119

    
120
        # connect signals and slots
121
        self.actionClose.triggered.connect(self.close)
122
        self.actionOpen.triggered.connect(self.openImageDrawing)
123
        #self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle)
124
        self.actionLine.triggered.connect(self.createLine)
125
        self.actionRecognition.triggered.connect(self.recognize)
126
        self.actionLineRecognition.triggered.connect(self.recognizeLine)
127
        self.actionArea.triggered.connect(self.areaConfiguration)
128
        self.actionConfiguration.triggered.connect(self.configuration)
129
        self.actionOCR.triggered.connect(self.areaOcr)
130
        self.actionGenerateOutput.triggered.connect(self.generateOutput)
131
        self.pushButtonCreateSymbol.clicked.connect(self.createSymbol)
132
        self.actionEquipment.triggered.connect(self.createEquipment)
133
        self.actionNozzle.triggered.connect(self.createNozzle)
134
        self.graphicsView.scene.changed.connect(lambda: self.resultTreeWidget.sceneChanged(self.graphicsView.scene.items()))
135

    
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
    '''
166
        @brief      Area OCR
167
        @author     Jeongwoo
168
        @date       18.04.18
169
        @history    2018.05.02  Jeongwoo    Change graphicsView.command by actionOCR checked state
170
                                            Show MessageBox when imageviewer doesn't have image
171
    '''
172
    def areaOcr(self):
173
        if not self.graphicsView.hasImage():
174
            self.showImageSelectionMessageBox()
175
            return
176

    
177
        if self.actionOCR.isChecked():
178
            self.graphicsView.command = AreaOcrCommand.AreaOcrCommand(self.graphicsView)
179
        else:
180
            self.graphicsView.useDefaultCommand()
181
    
182
    '''
183
        @brief  area configuration
184
    '''
185
    def areaConfiguration(self):
186
        from QAreaConfigurationDialog import QAreaConfigurationDialog
187

    
188
        self.dlgAreaConfiguration = QAreaConfigurationDialog(self)
189
        self.dlgAreaConfiguration.show()
190
        self.dlgAreaConfiguration.exec_()
191

    
192
    '''
193
        @brief  configuration
194
    '''
195
    def configuration(self):
196
        from QConfigurationDialog import QConfigurationDialog
197

    
198
        self.dlgConfiguration = QConfigurationDialog(self)
199
        self.dlgConfiguration.show()
200
        self.dlgConfiguration.exec_()
201

    
202
    '''
203
        @brief  Show Image Selection Guide MessageBox
204
        @author Jeongwoo
205
        @date   2018.05.02
206
    '''
207
    def showImageSelectionMessageBox(self):
208
        QMessageBox.about(self.graphicsView, "알림", "이미지를 선택하신 후 시도해주세요.")
209
        
210
    '''
211
        @brief  Open image drawing file and then display it
212
        @author humkyung
213
        @date   2018.??.??
214
        @history    18.04.23    Jeongwoo    Add AppDocData.instance().setCurrentPidSource
215
                    18.04.23    Jeongwoo    Add Store Set Current Pid Image on AppDocData
216
                    18.05.02    Jeongwoo    Add useDefaultCommand()
217
    '''
218
    def openImageDrawing(self, MainWindow):
219
        import random
220

    
221
        try:
222
            self.graphicsView.clearImage()
223
            self.graphicsView.scene.clear()
224
            self.graphicsView.useDefaultCommand()
225
            self.path = self.graphicsView.loadImageFromFile()
226
            if os.path.isfile(self.path):
227
                baseName = os.path.basename(self.path)
228
                AppDocData.instance().setCurrentPidSource(Image.open(self.path))
229
                self.resultTreeWidget.setCurrentPID(baseName)
230

    
231
                # DEBUG
232
                '''
233
                if __debug__:
234
                    from LineDetector import LineDetector
235
                    from LineNoTracer import LineNoTracer
236
                    self.loadRecognitionResult('d:/Projects/DTIPID/DTI_PID/DTI_PID/SG_TEST/output/UY1-K-2005G_P1_300dpi_black.xml')
237

238
                    # detect line
239
                    connectedLines = []
240

241
                    img = cv2.cvtColor(cv2.imread(self.path), cv2.COLOR_BGR2GRAY)
242
                    detector = LineDetector(img)
243
                    symbols = []
244
                    for item in self.graphicsView.scene.items():
245
                        if type(item) is SymbolSvgItem:
246
                            symbols.append(item)
247
                            color = QColor(random.randrange(0,255), random.randrange(0,255), random.randrange(0,255))
248
                            res = detector.detectConnectedLine(item, 0, 0)
249
                            if res is not None:
250
                                for line in res: connectedLines.append(line)
251

252
                    texts = []
253
                    for item in self.graphicsView.scene.items():
254
                        if (type(item) is QEngineeringTextItem): texts.append(item)
255

256
                    if len(connectedLines) > 1:
257
                        detector.mergeLines(connectedLines, toler=20)
258
                        # connect line to symbol
259
                        try:
260
                            for line in connectedLines:
261
                                matches = [symbol for symbol in symbols if symbol.isConnectable(line, (0,0), toler=40)]
262
                                for symbol in matches:
263
                                    detector.connectLineToSymbol(line, (0,0), symbol)
264
                        except Exception as ex:
265
                            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
266
                        # up to here
267

268
                        # connect line to line
269
                        try:
270
                            for line in connectedLines[:]:
271
                                matches = [it for it in connectedLines if (line != it) and (not detector.isParallel(line, it))]
272
                                for match in matches:
273
                                    detector.connectLineToLine(match, line)
274
                        except Exception as ex:
275
                            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
276
                        # up to here
277

278
                    lines = []
279
                    for pts in connectedLines:
280
                        processLine = QEngineeringLineItem()
281
                        lines.append(processLine)
282
                        for pt in pts:
283
                            processLine._pol.append(QPointF(pt[0], pt[1]))
284
                        processLine._path.addPolygon(processLine._pol)
285
                        processLine.setPath(processLine._path)
286
                        processLine.setPen(QPen(color, 5, Qt.SolidLine))
287
                        self.graphicsView.scene.addItem(processLine)
288
                    detector.saveImage()
289

290
                    # trace line no
291
                    tracer = LineNoTracer(symbols, lines, texts)
292
                    tracer.execute()
293
                    # up to here
294

295
                    # construct line no item
296
                    docData = AppDocData.instance()
297
                    for text in docData.lineNos:
298
                        item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, text)
299

300
                        if 1 == len(text.conns):
301
                            # iterate connected items
302
                            pool = []
303
                            visited = []
304
                            pool.append(text.conns[0])
305
                            while len(pool) > 0:
306
                                it = pool.pop()
307
                                if type(it) is SymbolSvgItem: self.resultTreeWidget.addTreeItem(item, it)
308
                                visited.append(it)
309
                                for conn in it.conns:
310
                                    if (conn is not None) and (conn not in visited): pool.append(conn)
311
                            # up to here
312
                                
313
                    # up to here
314
                # up to here
315
                '''
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

    
319
        return self.path
320

    
321
    '''
322
        @brief  create a symbol
323
        @history    2018.05.02  Jeongwoo    Change return value of QSymbolEditorDialog (Single variable → Tuple)
324
                                            Add SymbolSvgItem
325
                    2018.05.03  Jeongwoo    Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
326
                                            Change method to make svg and image path
327
    '''
328
    def createSymbol(self):
329
        image = self.graphicsView.image()
330
        if image is not None:
331
            symbolEditorDialog = QSymbolEditorDialog.QSymbolEditorDialog(self, image, AppDocData.instance().getCurrentProject())
332
            (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
333
            self.dirTreeWidget.initDirTreeWidget()
334
            if isAccepted:
335
                if isImmediateInsert:
336
                    svgPath = newSym.getSvgFileFullPath()
337
                    img = cv2.imread(newSym.getImageFileFullPath(), 1)
338
                    w, h = (0, 0)
339
                    if len(img.shape[::-1]) == 2:
340
                        w, h = img.shape[::-1]
341
                    else:
342
                        _chan, w, h = img.shape[::-1]
343
                    svg = SymbolSvgItem(svgPath)
344
                    svg.buildItem(newSym.getName(), newSym.getType(), 0, [offsetX, 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('/')])
345

    
346
                    #### lambda param=svg : bind 'svg' object to lambda('param')
347
                    #### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda
348
                    svg.clicked.connect(lambda param=svg: self.resultTreeWidget.findItem(param))
349
                    svg.removed.connect(self.resultTreeWidget.itemRemoved)
350
                    svg.addSvgItemToScene(self.graphicsView.scene)
351
                    for connector in svg.connectors:
352
                        self.graphicsView.scene.addItem(connector)
353

    
354
    #'''
355
    #    @brief  connect equipment and nozzle
356
    #'''
357
    #def connectEqpNozzle(self):
358
    #    self.graphicsView.command = None
359

    
360
    '''
361
        @brief  create a line
362
        @author humkyung
363
    '''
364
    def createLine(self):
365
        # set imageviewer's command
366
        self.graphicsView.command = CreateCommand.CreateCommand(self.graphicsView, QEngineeringLineItem())
367
        # up to here
368

    
369
    '''
370
        @brief      recognize symbol and text
371
        @author     humkyung
372
        @date       2018.04.??
373
        @history    2018.04.16  humkyung    execute line no tracing
374
                    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
375
    '''
376
    def recognize(self, MainWindow):
377
        from QRecognitionDialog import QRecognitionDialog
378

    
379
        if not self.graphicsView.hasImage():
380
            self.showImageSelectionMessageBox()
381
            return
382

    
383
        try:
384
            self.dlg = QRecognitionDialog(self)
385
            self.startThread()
386
            self.dlg.show()
387
            self.dlg.exec_()
388
            if self.dlg.isAccepted == True:
389
                self.loadRecognitionResult(self.xmlPath[0])
390
        except Exception as ex:
391
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
392

    
393
    '''
394
        @brief  remove small objects from given image
395
        @author humkyung
396
        @date   2018.04.26
397
    '''
398
    def removeSmallObjects(self, image):
399
        try:
400
            docData = AppDocData.instance()
401
            configs = docData.getConfigs('Small Object Size', 'Min Area')
402
            minArea = int(configs[0].value) if 1 == len(configs) else 20
403
            configs = docData.getConfigs('Small Object Size', 'Max Area')
404
            maxArea = int(configs[0].value) if 1 == len(configs) else 50
405

    
406
            #path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), 'before_contours.png')
407
            #cv2.imwrite(path, image)
408

    
409
            _,contours,_ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
410
            selectedContours=[]
411
            for contour in contours:
412
                #if cv2.isContourConvex(contour):
413
                    #approx = cv2.approxPolyDP(contour, 0.2*cv2.arcLength(contour, True), True)
414
                area = cv2.contourArea(contour)
415
                if area > minArea and area < maxArea: selectedContours.append(contour)
416
            contourImage = cv2.drawContours(image, selectedContours, -1, (255,255,255), -1);
417
            #path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), 'contours.png')
418
            #cv2.imwrite(path, contourImage)
419
        except Exception as ex:
420
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
421

    
422
        return contourImage
423

    
424
    '''
425
        @brief      recognize line
426
        @author     humkyung
427
        @date       2018.04.19
428
        @history    2018.04.26 Jeongwoo Variable name changed (texts → lineNos)
429
                                        TextItem type changed (QEngineeringTextItem → QEngineeringLineNoTextItem)
430
        @history    2018.04.26 humkyung remove small objects before recognizing line
431
                    2018.05.02 Jeongwoo Show MessageBox when imageviewer doesn't have image
432
                    
433
    '''
434
    def recognizeLine(self, MainWindow):
435
        from LineDetector import LineDetector
436
        from LineNoTracer import LineNoTracer
437

    
438
        if not self.graphicsView.hasImage():
439
            self.showImageSelectionMessageBox()
440
            return
441

    
442
        try:
443
            #remove already existing line item
444
            items = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem]
445
            for item in items:
446
                self.graphicsView.scene.removeItem(item)
447
            #up to here
448

    
449
            # detect line
450
            connectedLines = []
451

    
452
            area = AppDocData.instance().getArea('Drawing')
453
            area.img = self.removeSmallObjects(area.img)
454
            detector = LineDetector(area.img)
455

    
456
            symbols = []
457
            for item in self.graphicsView.scene.items():
458
                if issubclass(type(item), SymbolSvgItem):
459
                    symbols.append(item)
460
                    res = detector.detectConnectedLine(item, round(area.x), round(area.y))
461
                    if res is not None:
462
                        for line in res: connectedLines.append(line)
463

    
464
            texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)]
465
            for symbol in symbols:
466
                symbol.connectAttribute(texts)
467

    
468
            lineNos = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineNoTextItem]
469

    
470
            if len(connectedLines) > 1:
471
                detector.mergeLines(connectedLines, toler=20)
472
                # connect line to symbol
473
                try:
474
                    for line in connectedLines:
475
                        matches = [symbol for symbol in symbols if symbol.isConnectable(line, (round(area.x), round(area.y)), toler=20)]
476
                        for symbol in matches:
477
                            detector.connectLineToSymbol(line, (round(area.x), round(area.y)), symbol)
478
                except Exception as ex:
479
                    print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
480
                # up to here
481

    
482
                # connect line to line
483
                try:
484
                    for line in connectedLines[:]:
485
                        matches = [it for it in connectedLines if (line != it) and (not detector.isParallel(line, it))]
486
                        for match in matches:
487
                            detector.connectLineToLine(match, line)
488
                except Exception as ex:
489
                    print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
490
                # up to here
491

    
492
            lines = []
493
            for pts in connectedLines:
494
                processLine = QEngineeringLineItem()
495
                lines.append(processLine)
496
                for pt in pts:
497
                    processLine._pol.append(QPointF(pt[0] + round(area.x), pt[1] + round(area.y)))
498
                processLine.buildItem()
499
                processLine.setPen(QPen(Qt.blue, 5, Qt.SolidLine))
500
                self.graphicsView.scene.addItem(processLine)
501

    
502
            # trace line no
503
            tracer = LineNoTracer(symbols, lines, lineNos)
504
            tracer.execute()
505
            # up to here
506

    
507
            # construct line no item
508
            docData = AppDocData.instance()
509
            for text in docData.lineNos:
510
                item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, text)
511
                connectedItems = text.getConnectedItems()
512
                for connectedItem in connectedItems:
513
                    if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(item, connectedItem)
514
            # up to here
515
        except Exception as ex:
516
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
517

    
518
    '''
519
        @brief      load recognition result
520
        @author     humkyung
521
        @date       2018.04.??
522
        @history    humkyung 2018.01.12 parse originalpoint and connectionpoint
523
                    Jeongwoo 2018.04.17 add QGraphicItem with Rotated text
524
                    Jeongwoo 2018.04.23 Change to Draw texts on QEngineeringTextItem
525
                    humkyung 2018.04.23 connect item remove slot to result tree
526
                    Jeongwoo 2018.04.25 Add if state with QEngineeringNoteItem
527
                    Jeongwoo 2018.04.26 Change method to create TextItem object with TextItemFactory
528
                    Jeongwoo 2018.05.03 Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
529
    '''
530
    def loadRecognitionResult(self, xmlPath):
531
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
532

    
533
        try:
534
            project = AppDocData.instance().getCurrentProject()
535

    
536
            xml = parse(xmlPath)
537
            root = xml.getroot();
538
            for symbol in root.iter('SYMBOL'):
539
                pt = [float(x) for x in symbol.find('STARTPOINT').text.split(',')]
540
                size = [float(x) for x in symbol.find('SIZE').text.split(',')]
541
                name = symbol.find('NAME').text
542
                angle = float(symbol.find('ANGLE').text)
543
                type = symbol.find('TYPE').text
544
                origin = [float(x) for x in symbol.find('ORIGINALPOINT').text.split(',')]
545
                connPts = []
546
                if symbol.find('CONNECTIONPOINT').text is not None:
547
                    connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) for x in symbol.find('CONNECTIONPOINT').text.split('/')]
548
                
549
                svgFilePath = os.path.join(project.getSvgFilePath(), type, name + '.svg')
550
                if os.path.isfile(svgFilePath):
551
                    svg = SymbolSvgItem.createItem(type, svgFilePath)
552
                    svg.buildItem(name, type, angle, pt, size, origin, connPts)
553

    
554
                    #### lambda param=svg : bind 'svg' object to lambda('param')
555
                    #### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda
556
                    svg.clicked.connect(lambda param=svg: self.resultTreeWidget.findItem(param))
557
                    svg.removed.connect(self.resultTreeWidget.itemRemoved)
558
                    svg.addSvgItemToScene(self.graphicsView.scene)
559
                    for connector in svg.connectors:
560
                        self.graphicsView.scene.addItem(connector)
561
                else:
562
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
563
                    item.isSymbol = True
564
                    item.angle = angle
565
                    item.setPen(QPen(Qt.red, 20, Qt.SolidLine))
566
                    self.graphicsView.scene.addItem(item)
567

    
568
            docData = AppDocData.instance()
569
            configs = docData.getConfigs('Line No', 'Delimiter')
570
            delimiter = configs[0].value if 1 == len(configs) else '-'
571
            lineNoconfigs = docData.getConfigs('Line No', 'Configuration')
572
            # parse texts
573
            for text in root.iter('TEXTINFO'):
574
                x = float(text.find('X').text) if text.find('X') is not None else 0
575
                y = float(text.find('Y').text) if text.find('Y') is not None else 0
576
                width = float(text.find('WIDTH').text) if text.find('WIDTH') is not None else 0
577
                height = float(text.find('HEIGHT').text) if text.find('HEIGHT') is not None else 0
578
                angle = float(text.find('ANGLE').text) if text.find('ANGLE') is not None else 0
579
                text = text.find('TEXT').text
580
                item = TextItemFactory.instance().createTextItem(text, delimiter, lineNoconfigs)
581
                if item is not None:
582
                    item.loc = (x, y)
583
                    item.size = (width, height)
584
                    item.angle = angle
585
                    item.setPlainText(text)
586
                    item.setDefaultTextColor(Qt.blue)
587
                    item.removed.connect(self.resultTreeWidget.itemRemoved)
588
                    item.addTextItemToScene(self.graphicsView.scene)
589

    
590
            # parse notes
591
            for note in root.iter('NOTE'):
592
                x = float(note.find('X').text) if note.find('X') is not None else 0
593
                y = float(note.find('Y').text) if note.find('Y') is not None else 0
594
                width = float(note.find('WIDTH').text) if note.find('WIDTH') is not None else 0
595
                height = float(note.find('HEIGHT').text) if note.find('HEIGHT') is not None else 0
596
                angle = float(note.find('ANGLE').text) if note.find('ANGLE') is not None else 0
597
                text = note.find('TEXT').text
598
                item = TextItemFactory.instance().createTextItem(text)
599
                item.loc = (x, y)
600
                item.size = (width, height)
601
                item.angle = angle
602
                item.setPlainText(text)
603
                item.setDefaultTextColor(Qt.blue)
604
                item.addTextItemToScene(self.graphicsView.scene)
605
                
606
                #self.graphicsView.scene.addItem(item)
607
            # up to here
608
        except Exception as ex:
609
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
610

    
611
    '''
612
        @brief  generate output xml file
613
        @author humkyung
614
        @date   2018.04.23
615
        @history    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
616
    '''
617
    def generateOutput(self):
618
        import XmlGenerator as xg
619

    
620
        if not self.graphicsView.hasImage():
621
            self.showImageSelectionMessageBox()
622
            return
623

    
624
        try:
625
            docData = AppDocData.instance()
626
            
627
            # TODO: how to check equipment
628
            docData.equipments.clear()
629
            for item in self.graphicsView.scene.items():
630
                if (type(item) is SymbolSvgItem) and item.type == 'Specialty Components':
631
                    docData.equipments.append(item)
632
            # up to here
633

    
634
            xg.writeOutputXml(docData.imgName, docData.imgWidth, docData.imgHeight)
635
        except Exception as ex:
636
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
637

    
638
    '''
639
        @brief  start thread
640
        @author humkyung
641
        @date   2018.04.??
642
    '''
643
    def startThread(self):
644
        self.dlg.ui.buttonBox.setDisabled(True)
645

    
646
        # 1 - create Worker and Thread inside the Form
647
        self.obj = Worker()  # no parent!
648
        self.obj.path = self.path
649
        self.obj.listWidget = self.dlg.ui.listWidget
650
        self.thread = QThread()  # no parent!
651

    
652
        # 2 - Connect Worker`s Signals to Form method slots to post data.
653
        #self.obj.intReady.connect(self.onIntReady)
654

    
655
        # 3 - Move the Worker object to the Thread object
656
        self.obj.moveToThread(self.thread)
657

    
658
        # 4 - Connect Worker Signals to the Thread slots
659
        self.obj.finished.connect(self.thread.quit)
660

    
661
        # 5 - Connect Thread started signal to Worker operational slot method
662
        self.thread.started.connect(self.obj.procCounter)
663

    
664
        # * - Thread finished signal will close the app if you want!
665
        self.thread.finished.connect(self.dlgExit)
666

    
667
        # 6 - Start the thread
668
        self.thread.start()
669

    
670
    '''
671
        @brief set buttonbox's enabled flag
672
    '''
673
    def dlgExit(self):
674
        self.xmlPath = self.obj.xmlPath
675
        self.dlg.ui.buttonBox.setEnabled(True)
676

    
677
if __name__ == '__main__':
678
    import DTI_PID_UI
679
    from ProjectDialog import Ui_Dialog
680
    from App import App 
681

    
682
    app = App(sys.argv)
683
    try:
684
        dlg = Ui_Dialog()
685
        selectedProject = dlg.showDialog()
686
        if selectedProject is not None:
687
            AppDocData.instance().setCurrentProject(selectedProject)
688
            app.mainWnd = MainWindow.instance()
689
            app.mainWnd.show()
690
    except Exception as ex:
691
        print('에러가 발생했습니다.\n', ex)
692

    
693
    sys.exit(app.exec_())
클립보드 이미지 추가 (최대 크기: 500 MB)