프로젝트

일반

사용자정보

개정판 dc05dcb9

IDdc05dcb978ebbd1094c6dfe2fe212b40c4970d55
상위 217bfefe
하위 d301a511

백흠경이(가) 6년 이상 전에 추가함

fixed issue #103:
- Unknown 항목들을 선택후 심볼 등록

차이점 보기:

DTI_PID/DTI_PID/Commands/CreateSymbolCommand.py
14 14
from AppDocData import AppDocData
15 15
import cv2
16 16
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
17
import QSymbolEditorDialog
17
import SymbolEditorDialog
18 18
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\Shapes')
19 19
from SymbolSvgItem import SymbolSvgItem
20 20

  
......
51 51
                selectionBBox = self.imageViewer.scene.selectionArea().boundingRect().intersected(viewBBox)
52 52
                if selectionBBox.isValid():
53 53
                    croppedImage = self.imageViewer.image().copy(selectionBBox.toAlignedRect())
54
                    symbolEditorDialog = QSymbolEditorDialog.QSymbolEditorDialog(self.imageViewer, croppedImage, AppDocData.instance().getCurrentProject())
54
                    symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self.imageViewer, croppedImage, AppDocData.instance().getCurrentProject())
55 55
                    (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
56 56
                    self.dirTreeWidget.initDirTreeWidget()
57 57
                    if isAccepted:
DTI_PID/DTI_PID/DTI_PID.pyproj
78 78
    <Compile Include="ItemPropertyTableWidget.py" />
79 79
    <Compile Include="ItemTreeWidget.py" />
80 80
    <Compile Include="QSymbolDisplayDialog.py" />
81
    <Compile Include="QSymbolEditorDialog.py" />
81
    <Compile Include="SymbolEditorDialog.py" />
82 82
    <Compile Include="QtImageViewer.py">
83 83
      <SubType>Code</SubType>
84 84
    </Compile>
DTI_PID/DTI_PID/ItemPropertyTableWidget.py
46 46
        @date   2018.07.03
47 47
    '''
48 48
    def showItemProperty(self, item):
49
        if type(item) is QEngineeringLineItem:
50
            self.initTitleCell(item)
51
            self.setItem(0, 1, QTableWidgetItem(str(item.uid)))
52
            self.setItem(1, 1, QTableWidgetItem(item.lineType))
53
            pt = item.startPoint()
54
            self.setItem(2, 1, QTableWidgetItem('({},{})'.format(pt[0], pt[1])))
55
            pt = item.endPoint()
56
            self.setItem(3, 1, QTableWidgetItem('({},{})'.format(pt[0], pt[1])))
57
            self.setItem(4, 1, QTableWidgetItem('{}'.format('None' if item.connectors[0].connectedItem is None else item.connectors[0].connectedItem.uid)))
58
            self.setItem(5, 1, QTableWidgetItem('{}'.format('None' if item.connectors[1].connectedItem is None else item.connectors[1].connectedItem.uid)))
59
        elif issubclass(type(item), SymbolSvgItem):
60
            self.onSymbolClicked(item)
61
        elif type(item) is QEngineeringLineNoTextItem:
62
            self.onLineNoClicked(item)
63
        elif type(item) is QEngineeringNoteItem:
64
            self.onNoteClicked(item)
49
        try:
50
            if type(item) is QEngineeringLineItem:
51
                self.initTitleCell(item)
52
                self.setItem(0, 1, QTableWidgetItem(str(item.uid)))
53
                self.setItem(1, 1, QTableWidgetItem(item.lineType))
54
                pt = item.startPoint()
55
                self.setItem(2, 1, QTableWidgetItem('({},{})'.format(pt[0], pt[1])))
56
                pt = item.endPoint()
57
                self.setItem(3, 1, QTableWidgetItem('({},{})'.format(pt[0], pt[1])))
58
                self.setItem(4, 1, QTableWidgetItem('{}'.format('None' if item.connectors[0].connectedItem is None else item.connectors[0].connectedItem.uid)))
59
                self.setItem(5, 1, QTableWidgetItem('{}'.format('None' if item.connectors[1].connectedItem is None else item.connectors[1].connectedItem.uid)))
60
            elif issubclass(type(item), SymbolSvgItem):
61
                self.onSymbolClicked(item)
62
            elif type(item) is QEngineeringLineNoTextItem:
63
                self.onLineNoClicked(item)
64
            elif type(item) is QEngineeringNoteItem:
65
                self.onNoteClicked(item)
66
        except Exception as ex:
67
            from App import App 
68

  
69
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
70
            App.mainWnd().addMessage(MessageType.Error, message)
65 71

  
66 72
    '''
67 73
        @brief      Initialize TableWidget
DTI_PID/DTI_PID/ItemTreeWidget.py
19 19
from QEngineeringNoteItem import QEngineeringNoteItem
20 20
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
21 21
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
22
from QEngineeringUnknownItem import QEngineeringUnknownItem
22
from EngineeringUnknownItem import QEngineeringUnknownItem
23 23
from AppDocData import AppDocData
24 24
from Drawing import Drawing
25 25

  
DTI_PID/DTI_PID/MainWindow.py
35 35
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
36 36
from QEngineeringNoteItem import QEngineeringNoteItem
37 37
from QEngineeringSizeTextItem import QEngineeringSizeTextItem
38
from QEngineeringUnknownItem import QEngineeringUnknownItem
38
from EngineeringUnknownItem import QEngineeringUnknownItem
39 39
from AppDocData import *
40 40
import SymbolTreeWidget, PropertyTableWidget
41
import QSymbolEditorDialog
41
import SymbolEditorDialog
42 42
import ItemTreeWidget
43 43
import ItemPropertyTableWidget
44 44
from TextItemFactory import TextItemFactory
......
591 591
        try:
592 592
            image = self.graphicsView.image()
593 593
            if image is not None:
594
                symbolEditorDialog = QSymbolEditorDialog.QSymbolEditorDialog(self, image.copy(x, y, width, height), AppDocData.instance().getCurrentProject())
594
                symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image.copy(x, y, width, height), AppDocData.instance().getCurrentProject())
595 595
                (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
596 596
                self.dirTreeWidget.initDirTreeWidget()
597 597
                if isAccepted:
......
913 913
    def drawUnknownItems(self):
914 914
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem 
915 915
        from EngineeringLineItem import QEngineeringLineItem
916
        from QEngineeringUnknownItem import QEngineeringUnknownItem
916
        from EngineeringUnknownItem import QEngineeringUnknownItem
917 917

  
918 918
        try:
919 919
            docData = AppDocData.instance()
DTI_PID/DTI_PID/QSymbolEditorDialog.py
1
# coding: utf-8
2
from PyQt5 import QtCore, QtGui, QtWidgets
3
from PyQt5.QtCore import pyqtSlot, QRectF
4
from PyQt5.QtWidgets import *
5
from PyQt5.QtGui import *
6
from QtImageViewer import QtImageViewer
7
import os
8
import sqlite3
9
import sys
10
import symbol, SymbolBase
11
import potrace
12
import numpy as np
13
import cv2
14

  
15
import SymbolEditor_UI
16
from AppDocData import AppDocData
17

  
18
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
19
import CropCommand, HandCommand, ZoomCommand, PenCommand, EraserCommand, AreaEraserCommand, OriginalPointCommand, ConnectionPointCommand, AreaZoomCommand, FitImageCommand, RemoveTextCommand, RotateImageCommand, FlipImageCommand
20

  
21

  
22
class QSymbolEditorDialog(QDialog):
23
    FILE_NUMBER = 0
24

  
25
    '''
26
        @history    2018.05.02  Jeongwoo    Add variables (self.offsetX, self.offsetY, self.newSym)
27
                    2018.05.03  Jeongwoo    Remove parameter in SG_DbHelper()
28
                                            Remove self.dbHelper variable
29
                    2018.07.03  Yecheol     Rename File, Is Instrument Label added
30
    '''
31
    def __init__(self, parent, image, project, selectedSymbol = None):
32
        QDialog.__init__(self, parent)
33

  
34
        try:
35
            self.image = image
36
            self.selectedSymbol = selectedSymbol
37
            self.project = project
38
            self.ui = SymbolEditor_UI.Ui_Dialog()
39
            self.ui.setupUi(self)
40
            self.setupImageViewer()
41
            self.setupTools()
42
            self.initForms()
43
            self.initContents()
44
            self.isAccepted = False
45
            self.offsetX = 0
46
            self.offsetY = 0
47
            self.newSym = None
48

  
49
            self.setWindowTitle('심볼 편집기')
50
        except Exception as ex:
51
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
52

  
53
    def convertQImageToMat(self, incomingImage):
54
        '''  Converts a QImage into an opencv MAT format  '''
55

  
56
        try:
57
            incomingImage = incomingImage.convertToFormat(QImage.Format_RGBA8888)
58

  
59
            width = incomingImage.width()
60
            height = incomingImage.height()
61

  
62
            ptr = incomingImage.bits()
63
            ptr.setsize(incomingImage.byteCount())
64
            arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
65
            return arr
66
        except Exception as ex:
67
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
68

  
69
    '''
70
        @brief  Set up QtImageViewer and QImage
71
        @history    2018.05.02  Jeongwoo    Connect imageviewer and QSymbolEditorDialog
72
    '''
73
    def setupImageViewer(self):
74
        from MainWindow import MainWindow
75

  
76
        x = self.ui.imageViewContainer.x()
77
        y = self.ui.imageViewContainer.y()
78
        width = self.ui.imageViewContainer.frameGeometry().width()
79
        height = self.ui.imageViewContainer.frameGeometry().height()
80
        self.ui.imageView = QtImageViewer(MainWindow.instance())
81
        self.ui.imageView.setGeometry(QtCore.QRect(0, y, height, height))
82
        self.ui.imageView.aspectRatioMode = QtCore.Qt.KeepAspectRatio
83
        self.ui.imageView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
84
        self.ui.imageView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
85
        self.ui.imageView.canZoom = True
86
        self.ui.imageView.canPan = True
87
        image = self.image.copy()
88
        self.imgW = image.width()
89
        self.imgH = image.height()
90
        image = image.scaled(self.imgW, self.imgH)
91
        self.ui.imageView.setImage(image)
92
        self.ui.imageViewerContainerLayout.addWidget(self.ui.imageView)
93
        self.ui.imageView.startPointChanged.connect(self.offsetChanged)
94

  
95
    '''
96
        @brief  Set up Hand, Crop, ETC Tools
97
        @history    2018.05.03  Jeongwoo    Add connection for removeTextButton
98
                    2018.06.11  Jeongwoo    Add connection for rotation and flip
99
    '''
100
    def setupTools(self):
101
        self.ui.handButton.clicked.connect(self.handToolClickEvent)
102
        self.ui.cropButton.clicked.connect(self.cropToolClickEvent)
103
        self.ui.penButton.clicked.connect(self.penToolClickEvent)
104
        self.ui.penWidthSpinBox.valueChanged.connect(self.penWidthChangedEvent)
105
        self.ui.eraserButton.clicked.connect(self.eraserToolClickEvent)
106
        self.ui.eraserSpinBox.valueChanged.connect(self.eraserWidthChangedEvent)
107
        self.ui.areaEraserButton.clicked.connect(self.areaEraserToolClickEvent)
108
        self.ui.fitImageButton.clicked.connect(self.fitImageToolClickEvent)
109
        self.ui.zoomButton.clicked.connect(self.zoomToolClickEvent)
110
        self.ui.areaZoomButton.clicked.connect(self.areaZoomToolClickEvent)
111
        self.ui.initZoomButton.clicked.connect(self.zoomInitToolClickEvent)
112
        self.ui.guidelineCheckbox.stateChanged.connect(self.guidelineStateChangedEvent)
113
        #self.ui.additionalSymbolListWidget.keyPressEvent.connect(self.additionalSymbolListKeyPressEvent)
114
        #self.ui.connectionPointList.keyPressEvent.connect(self.additionalSymbolListKeyPressEvent)
115
        self.ui.removeTextButton.clicked.connect(self.removeTextClickEvent)
116
        self.ui.rotateLeftButton.clicked.connect(self.rotateLeftClickEvent)
117
        self.ui.rotateRightButton.clicked.connect(self.rotateRightClickEvent)
118
        self.ui.flipHorizontalButton.clicked.connect(self.flipHorizontalClickEvent)
119
        self.ui.flipVerticalButton.clicked.connect(self.flipVerticalClickEvent)
120

  
121
    '''
122
        @brief  Init Forms with type and default values
123
    '''
124
    def initForms(self):
125
        #self.ui.idLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[1-9]\d+$")))
126
        self.ui.thresholdLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) # ([0-1]{1}[.])?[0-9]+
127
        self.ui.minMatchPointLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$")))
128
        self.initDefaultSymbolDirectionComboBoxItems()
129
        self.ui.addAdditionalSymbolButton.clicked.connect(self.addAdditionalSymbolEvent)
130
        self.ui.addOriginalPointButton.clicked.connect(self.addOriginalPoint)
131
        self.ui.addConnectionPointButton.clicked.connect(self.addConnectionPoint)
132
        self.initSymbolTypeComboBoxItems()
133
        self.initBaseSymbolComboBoxItems(None)
134
        self.initAdditionalSymbolComboBoxItems()
135

  
136
    '''
137
        @brief      Init Symbol Type ComboBox Items
138
        @author     Jeongwoo
139
        @date       2018.04.06
140
        @history    .
141
    '''
142
    def initSymbolTypeComboBoxItems(self):
143
        for item in AppDocData.instance().getSymbolTypeComboBoxItems():
144
            self.ui.typeComboBox.addItem(item)
145
        self.ui.typeComboBox.currentTextChanged.connect(self.symbolTypeTextChagedEvent)
146

  
147
    def symbolTypeTextChagedEvent(self, value):
148
        self.initBaseSymbolComboBoxItems(value)
149
        
150
    '''
151
        @brief  Set data on forms, For modifying symbol
152
        @history    2018.05.02  Jeongwoo    When modifying symbol, Make immediateInsertCheckBox disable
153
        @           2018.07.04  Yecheol     Remove is Symbol ID(idLineEdit)
154
    '''
155
    def initContents(self):
156
        if self.selectedSymbol is not None:
157
            self.ui.immediateInsertCheckBox.setDisabled(True)
158

  
159
            #self.ui.idLineEdit.setText(str(self.selectedSymbol.getId()))
160
            self.ui.nameLineEdit.setText(self.selectedSymbol.getName())
161
            self.ui.thresholdLineEdit.setText(str(int(self.selectedSymbol.getThreshold() * 100)))
162
            self.ui.minMatchPointLineEdit.setText(str(self.selectedSymbol.getMinMatchCount()))
163
            self.ui.rotationCountSpinBox.setValue(self.selectedSymbol.getRotationCount())
164
            self.ui.isContainChildCheckBox.setChecked(True if self.selectedSymbol.getIsContainChild() else False)
165
            self.ui.typeComboBox.setCurrentIndex(self.ui.typeComboBox.findText(self.selectedSymbol.getType()))
166
            self.ui.baseSymbolComboBox.setCurrentIndex(self.ui.baseSymbolComboBox.findText(self.selectedSymbol.getBaseSymbol()))
167
            self.ui.isExceptDetectCheckBox.setChecked(True if self.selectedSymbol.getIsExceptDetect() else False)
168
            
169
            '''
170
                @Auther     Yecheol
171
                @Date       2018.07.03
172
                @History    isInstrumentLabel add
173
            '''
174
            self.ui.hasInstrumentLabelCheckBox.setChecked(True if self.selectedSymbol.getHasInstrumentLabel() else False)
175

  
176
            additionalSymbol = self.selectedSymbol.getAdditionalSymbol()
177
            if additionalSymbol is not None and len(additionalSymbol) > 0:
178
                splitAdditionalSymbolList = additionalSymbol.split("/")
179
                for symString in splitAdditionalSymbolList:
180
                    splitSymString = symString.split(",")
181
                    self.addAdditionalSymbol(splitSymString[0], splitSymString[1])
182

  
183
            originalPoint = self.selectedSymbol.getOriginalPoint()
184
            self.ui.originalPointLineEdit.setText(originalPoint)
185
            OriginalPointCommand.OriginalPointCommand.drawCircle(self.ui.imageView, originalPoint.split(",")[0], originalPoint.split(",")[1])
186
            self.ui.imageView.isOriginalPointSelected = True
187

  
188
            connectionPoint = self.selectedSymbol.getConnectionPoint()
189
            if connectionPoint is not None and len(connectionPoint) > 0:
190
                splitConnectionPointList = connectionPoint.split("/")
191
                for conString in splitConnectionPointList: # conString : x,y
192
                    self.ui.connectionPointList.addItem(conString)
193
                    ConnectionPointCommand.ConnectionPointCommand.drawCircle(self.ui.imageView, conString.split(",")[0], conString.split(",")[1])
194

  
195
    '''
196
        @brief  Init ComboBox Items For Direction of DB Field [additionalSymbol]
197
    '''
198
    def initDefaultSymbolDirectionComboBoxItems(self):
199
        for item in AppDocData.instance().getDefaultSymbolDirectionComboBoxItems():
200
            self.ui.defaultSymbolDirectionComboBox.addItem(item[0], item[1]) # 0 : text / 1 : data(integer)
201
        
202
    '''
203
        @brief  Init ComboBox Items For DB Field [baseSymbol]
204
    '''
205
    def initBaseSymbolComboBoxItems(self, type):
206
        self.ui.baseSymbolComboBox.clear()
207
        for item in AppDocData.instance().getBaseSymbolComboBoxItems(type):
208
            self.ui.baseSymbolComboBox.addItem(item)
209
            
210
    '''
211
        @brief  Init ComboBox Items For symbolName of DB Field [additionalSymbol]
212
    '''
213
    def initAdditionalSymbolComboBoxItems(self):
214
        for name in AppDocData.instance().getAdditionalSymbolComboBoxItems():
215
            self.ui.additionalSymbolComboBox.addItem(name)
216
    
217
    '''
218
        @brief  remove ConnectionPoint Circles (Using for loop)
219
    '''
220
    def removeConnectionPointCircles(self, circlePointList):
221
        for circlePoint in circlePointList:
222
            self.removeConnectionPointCircle(circlePoint)
223
            
224
    '''
225
        @brief  remove each ConnectionPoint Circle
226
        @history    2018.06.12  Jeongwoo    Add conditions for selecting ellipse item
227
    '''
228
    def removeConnectionPointCircle(self, circlePoint):
229
        imageWidth = self.ui.imageView.image().width()
230
        imageHeight = self.ui.imageView.image().height()
231
        items = self.ui.imageView.scene.items(QRectF(float(circlePoint.x())-0.5, float(circlePoint.y())-0.5, 1, 1))
232
        for item in items:
233
            if item is not None and item.boundingRect() != QRectF(0, 0, imageWidth, imageHeight) and type(item) is QGraphicsEllipseItem:
234
                color = item.brush().color().name()
235
                if color.upper() == '#0000FF' and item.boundingRect().center() == circlePoint:
236
                    self.ui.imageView.scene.removeItem(item)
237
        
238
    '''
239
        @brief  Display this QDialog
240
        @history    2018.05.02  Jeongwoo    Change return value (Single variable → Tuple)
241
    '''
242
    def showDialog(self):
243
        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
244
        #self.show()
245
        self.exec_()
246
        return (self.isAccepted, self.ui.immediateInsertCheckBox.isChecked(), self.offsetX, self.offsetY, self.newSym)
247
    
248
    '''
249
        @brief  Using input [Name], make file name
250
                If the [Name] exists, add number like [FILE_NAME(1), FILE_NAME(2), ...]
251
                Recursive function
252
        @history    2018.05.02  Jeongwoo    Change isExistFileName's parameter (Dir → newName)
253
                    2018.05.03  Jeongwoo    Change self.dbHelper to AppDocData
254
    '''
255
    def makeFileName(self, type, originName, newName):
256
        imageFolderDir = self.project.getImageFilePath()
257
        imageDir = os.path.join(imageFolderDir, type, newName + '.png')
258
        svgFolderDir = self.project.getSvgFilePath()
259
        svgDir = os.path.join(svgFolderDir, type, newName + '.svg')
260
        if (os.path.exists(imageDir)) or (AppDocData.instance().isExistFileName(newName) or (os.path.exists(svgDir))):
261
            self.FILE_NUMBER = self.FILE_NUMBER + 1
262
            imgName = originName + "({})".format(self.FILE_NUMBER)
263
            return self.makeFileName(type, originName, imgName)
264
        else:
265
            return newName
266
        
267
    '''
268
        @brief  Make symbol object for saving on DB
269
        @history    2018.05.02  Jeongwoo    newSym object changed self.newSym
270
    '''
271
    def makeSymbolData(self):
272
        uid = -1
273
        if self.selectedSymbol is not None:
274
            uid = self.selectedSymbol.getUid()
275
        #symId = self.ui.idLineEdit.text()
276
        name = self.ui.nameLineEdit.text()
277
        type = self.ui.typeComboBox.currentText() #Empty
278
        self.FILE_NUMBER = 0
279
        lastName = ""
280
        if self.selectedSymbol is not None:
281
            lastName = self.selectedSymbol.getName()
282
        fileName = ""
283
        if name == lastName:
284
            fileName = name
285
        else:
286
            fileName = self.makeFileName(type, name, name)
287
        threshold = self.ui.thresholdLineEdit.text()
288
        minMatchPoint = self.ui.minMatchPointLineEdit.text()
289
        rotationCount = self.ui.rotationCountSpinBox.value()
290
        ocrOption = 0
291
        isContainChild = 1 if self.ui.isContainChildCheckBox.isChecked() else 0
292
        originalPoint = self.ui.originalPointLineEdit.text()
293
        connectionPoint = self.makeConnectionPointListString()
294
        baseSymbol = self.ui.baseSymbolComboBox.currentText()
295
        additionalSymbol = self.makeAdditionalSymbolListString()
296
        isExceptDetect = 1 if self.ui.isExceptDetectCheckBox.isChecked() else 0
297

  
298
        '''
299
            @Auther Yechecol
300
            @Date   2018.07.03
301
            @History isInstrumentLabel add
302
                     SymbolBase parameter modified
303
        '''
304
        hasInstrumentLabel = 1 if self.ui.hasInstrumentLabelCheckBox.isChecked() else 0
305

  
306
        convertedThreshold = int(threshold) / 100.0
307

  
308
        self.newSym = symbol.SymbolBase(fileName, type, convertedThreshold, int(minMatchPoint), True, 
309
                        rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid)
310

  
311
        return self.newSym
312
    
313
    '''
314
        @brief  Make AdditionalSymbol String
315
                [AdditionalSymbolString = DIRECTION,SYMBOL_NAME/DIRECTION,SYMBOL_NAME/...]
316
    '''
317
    def makeAdditionalSymbolListString(self):
318
        ret = ""
319
        listItems = []
320
        for index in range(self.ui.additionalSymbolListWidget.count()):
321
            listItems.append(self.ui.additionalSymbolListWidget.item(index))
322
        if listItems is not None:
323
            for index in range(len(listItems)):
324
                item = listItems[index]
325
                text = item.text()
326
                if index != 0:
327
                    ret = ret + "/"
328
                ret = ret + text
329
        return ret
330
    
331
    '''
332
        @brief  Make ConnectionPoint String
333
                [ConnectionPointString = x1,y1/x2,y2/...]
334
    '''
335
    def makeConnectionPointListString(self):
336
        ret = ""
337
        listItems = []
338
        for index in range(self.ui.connectionPointList.count()):
339
            listItems.append(self.ui.connectionPointList.item(index))
340
        if listItems is not None:
341
            for index in range(len(listItems)):
342
                item = listItems[index]
343
                text = item.text()
344
                if index != 0:
345
                    ret = ret + "/"
346
                ret = ret + text
347
        return ret
348
    
349
    '''
350
        @brief  Called when Save Button Clicked
351
                Validation Check → Make Symbol Data → Insert Symbol Data into DB → Save png and svg files
352
        @history    2018.05.03  Jeongwoo    Change parameters on method 'deleteImageAndSvg'
353
                                            Change self.dbHelper to AppDocData
354
    '''
355
    def accept(self):
356
        isValid, exceptionMsg = self.isValidSymbolInfo()
357
        if isValid:
358
            if self.selectedSymbol is None:
359
                isSuccess, fileType, fileName, imagePath = AppDocData.instance().insertSymbol(self.makeSymbolData())
360
            else:
361
                isSuccess, fileType, fileName, imagePath = AppDocData.instance().updateSymbol(self.makeSymbolData())
362

  
363
            if isSuccess:
364
                try:
365
                    image = self.ui.imageView.image()
366
                    if image is not None:
367
                        if self.selectedSymbol is not None:
368
                            self.deleteImageAndSvg(self.selectedSymbol.getImageFileFullPath(), self.selectedSymbol.getSvgFileFullPath())
369
                        imageLocation = os.path.join(self.project.getImageFilePath(), fileType)
370
                        if not os.path.exists(imageLocation):
371
                            os.makedirs(imageLocation) 
372
                            
373
                        '''
374
                        arr = self.convertQImageToMat(image)
375
                        b = image.bits()
376
                        # sip.voidptr must know size to support python buffer interface
377
                        b.setsize(image.height() * image.width() * image.depth())
378
                        arr = np.frombuffer(b, np.uint8).reshape((image.height(), image.width(), image.bitPlaneCount()))
379
                        img = cv2.threshold(cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)[0]
380
                        cv2.imwrite(imagePath, img)
381
                        '''
382

  
383
                        image.save(imagePath, 'PNG')
384

  
385
                        svgLocation = os.path.join(self.project.getSvgFilePath(), fileType)
386
                        if not os.path.exists(svgLocation):
387
                            os.makedirs(svgLocation)
388
                        potrace.convertImageToSvg(imagePath, svgLocation + "/" + fileName + ".svg")
389
                        self.isAccepted = True
390
                        QDialog.accept(self)
391
                except:
392
                    if self.selectedSymbol is None:
393
                        self.resetInsertSymbol(imagePath, fileName)
394
                    else:
395
                        self.resetUpdateSymbol(imagePath, fileName) ### update roll back 으로 변경해야함
396
                    self.isAccepted = False
397
                    QMessageBox.about(self.ui.buttonBox, "알림", "심볼 저장 과정 중 문제가 발생했습니다.")
398
            else:
399
                QMessageBox.about(self.ui.buttonBox, "알림", "심볼 저장 과정 중 문제가 발생했습니다.")
400
        else:
401
            print("invalid symbol info")
402
            QMessageBox.about(self.ui.buttonBox, "알림", exceptionMsg)
403
            
404
    '''
405
        @brief  Called When Close Button Clicked
406
    '''
407
    def reject(self):
408
        self.isAccepted = False
409
        QDialog.reject(self)
410

  
411
    '''
412
        @history    2018.05.03  Jeongwoo    Change Parameters (imagePath, type, name → imagePath, svgPath)
413
    '''
414
    def deleteImageAndSvg(self, imagePath, svgPath):
415
        if os.path.exists(imagePath):
416
            os.remove(imagePath)
417

  
418
        if os.path.exists(svgPath):
419
            os.remove(svgPath)
420
        
421
    '''
422
        @brief  Called When error occured while saving png and svg files
423
                Delete png, svg files and record from DB
424
        @history    2018.05.03  Jeongwoo    Change Parameters and fileName variable
425
    '''
426
    def resetInsertSymbol(self, imagePath, svgPath):
427
        self.deleteImageAndSvg(imagePath, svgPath)
428

  
429
        fileName = os.path.basename(imagePath.replace('.png', ''))
430
        AppDocData.instance().deleteSymbol(fileName)
431

  
432
    '''
433
        @history    2018.05.03  Jeongwoo    Change Parameters
434
                                            Change self.dbHelper to AppDocData
435
    '''
436
    def resetUpdateSymbol(self, imagePath, svgPath):
437
        self.deleteImageAndSvg(imagePath, svgPath)
438

  
439
        AppDocData.instance().updateSymbol(self.selectedSymbol)
440

  
441
    '''
442
        @history    2018.06.12  Jeongwoo    coords type changed (int → float)
443
    '''
444
    def keyPressEvent(self, event):
445
        if event.key() == QtCore.Qt.Key_Delete:
446
            if self.ui.connectionPointList.hasFocus():
447
                selectedItems = self.ui.connectionPointList.selectedItems()
448
                if selectedItems is not None:
449
                    for item in selectedItems:
450
                        text = item.text()
451
                        x = float(text.split(",")[0])
452
                        y = float(text.split(",")[1])
453
                        self.removeConnectionPointCircle(QtCore.QPointF(x, y))
454
                        self.ui.connectionPointList.takeItem(self.ui.connectionPointList.row(item))
455
            elif self.ui.additionalSymbolListWidget.hasFocus():
456
                selectedItems = self.ui.additionalSymbolListWidget.selectedItems()
457
                if selectedItems is not None:
458
                    for item in selectedItems:
459
                        self.ui.additionalSymbolListWidget.takeItem(self.ui.additionalSymbolListWidget.row(item))
460
                        
461
    '''
462
        @brief  Hand Tool Button Clicked
463
    '''
464
    def handToolClickEvent(self, event):
465
        self.ui.imageView.command = HandCommand.HandCommand(self.ui.imageView)
466
        
467
    '''
468
        @brief  Crop Tool Button Clicked
469
        @history    2018.06.11  Jeongwoo    init original/connection points and guide line refresh
470
    '''
471
    def cropToolClickEvent(self, event):
472
        self.initOriginalAndConnectionPoint()
473
        self.ui.imageView.command = CropCommand.CropCommand(self.ui.imageView)
474
        self.guidelineStateChangedEvent(None)
475
                         
476
    '''
477
        @brief  Zoom Init Tool Button Clicked
478
    '''
479
    def zoomInitToolClickEvent(self, event):
480
        print("zoom init tool clicked")
481
        self.ui.imageView.command = None
482
        self.ui.imageView.zoomImageInit()
483

  
484
    '''
485
        @brief  Area Zoom Tool Button Clicked
486
    '''
487
    def areaZoomToolClickEvent(self, event):
488
        print("area zoom tool clicked")
489
        self.ui.imageView.command = AreaZoomCommand.AreaZoomCommand(self.ui.imageView)
490
                         
491
    '''
492
        @brief  Zoom Tool Button Clicked
493
    '''
494
    def zoomToolClickEvent(self, event):
495
        print("zoom tool clicked")
496
        self.ui.imageView.command = ZoomCommand.ZoomCommand(self.ui.imageView)
497
                         
498
    '''
499
        @brief  Pen Tool Button Clicked
500
    '''
501
    def penToolClickEvent(self, event):
502
        print("Pen")
503
        width = self.ui.toolWidget.findChild(QSpinBox, 'penWidthSpinBox').value()
504
        self.ui.imageView.command = PenCommand.PenCommand(self.ui.imageView)
505
        self.ui.imageView.command.width = width
506
                         
507
    '''
508
        @brief  Pen Width Value Changed
509
    '''
510
    def penWidthChangedEvent(self, value):
511
        print("Pen Width " + str(value))
512
        if self.ui.imageView.command is not None and type(self.ui.imageView.command) is PenCommand.PenCommand:
513
            self.ui.imageView.command.width = value
514
                 
515
    '''
516
        @brief  Eraser Tool Button Clicked
517
    '''
518
    def eraserToolClickEvent(self, event):
519
        print("eraser")
520
        width = self.ui.toolWidget.findChild(QSpinBox, 'eraserSpinBox').value()
521
        self.ui.imageView.command = EraserCommand.EraserCommand(self.ui.imageView)
522
        self.ui.imageView.command.width = width
523
                         
524
    '''
525
        @brief  Eraser Width Value Changed
526
    '''
527
    def eraserWidthChangedEvent(self, value):
528
        print("eraser " + str(value))
529
        if self.ui.imageView.command is not None and type(self.ui.imageView.command) is EraserCommand.EraserCommand:
530
            self.ui.imageView.command.width = value
531
                             
532
    '''
533
        @brief  Area Eraser Tool Button Clicked
534
    '''
535
    def areaEraserToolClickEvent(self, event):
536
        self.ui.imageView.command = AreaEraserCommand.AreaEraserCommand(self.ui.imageView)
537
                             
538
    '''
539
        @brief      Fit Image Tool Button Clicked
540
        @history    2018.05.02  Jeongwoo    Method name changed(getAdjust → getOffset)
541
                                            Emit offsets to startPointChanged
542
                    2018.06.11  Jeongwoo    init original/connection points
543
    '''
544
    def fitImageToolClickEvent(self, event):
545
        self.initOriginalAndConnectionPoint()
546
        self.ui.imageView.command = FitImageCommand.FitImageCommand(self.ui.imageView)
547
        adjustX, adjustY = self.ui.imageView.command.getOffset()
548
        #self.adjustOriginalPoint(adjustX, adjustY)
549
        #self.adjustConnectionPoint(adjustX, adjustY)
550
        self.ui.imageView.startPointChanged.emit(adjustX, adjustY)
551
                         
552
    '''
553
        @brief  Guideline Check State Changed
554
    '''
555
    def guidelineStateChangedEvent(self, value):
556
        if self.ui.guidelineCheckbox.isChecked():
557
            self.ui.imageView.showGuideline(True)
558
        else:
559
            self.ui.imageView.showGuideline(False)
560
                             
561
    '''
562
        @brief  Add AdditionalSymbol String on ListWidget Listener
563
    '''
564
    def addAdditionalSymbolEvent(self, event):
565
        additionalSymbolIndex = self.ui.additionalSymbolComboBox.currentIndex()
566
        if additionalSymbolIndex != 0:
567
            direction = self.ui.defaultSymbolDirectionComboBox.currentText()
568
            symbolName = self.ui.additionalSymbolComboBox.currentText()
569
            self.addAdditionalSymbol(direction, symbolName)
570
                    
571
    '''
572
        @brief  Add AdditionalSymbol String on ListWidget
573
    '''
574
    def addAdditionalSymbol(self, direction, symbolName):
575
        text = "{},{}".format(direction, symbolName)
576

  
577
        if self.isAlreadyAdded(text):
578
            QMessageBox.about(self.ui.buttonBox, "알림", "이미 추가된 아이템입니다.")
579
        else:
580
            self.ui.additionalSymbolListWidget.addItem(text)
581
                                 
582
    '''
583
        @brief  Check the text is already added
584
    '''
585
    def isAlreadyAdded(self, text):
586
        for index in range(self.ui.additionalSymbolListWidget.count()):
587
            item = self.ui.additionalSymbolListWidget.item(index)
588
            if item.text() == text:
589
                return True
590
        return False
591
                     
592
    '''
593
        @brief  Original Point Tool Button Clicked
594
    '''
595
    def addOriginalPoint(self, event):
596
        print("addOriginalPoint")
597
        self.ui.imageView.command = OriginalPointCommand.OriginalPointCommand(self.ui.imageView, self.ui.originalPointLineEdit)
598
                         
599
    '''
600
        @brief  Connection Point Tool Button Clicked
601
    '''
602
    def addConnectionPoint(self, event):
603
        print("addConnectionPoint")
604
        self.ui.imageView.command = ConnectionPointCommand.ConnectionPointCommand(self.ui.imageView, self.ui.connectionPointLineEdit, self.ui.connectionPointList)
605

  
606
    '''
607
        @brief  Remove Text Tool Button Clicked
608
        @author Jeongwoo
609
        @date   2018.05.03
610
        @history    2018.05.09  Jeongwoo    Remove comment and activate RemoveTextCommand
611
    '''
612
    def removeTextClickEvent(self, event):
613
        print("removeText")
614
        self.ui.imageView.command = RemoveTextCommand.RemoveTextCommand(self.ui.imageView)
615

  
616
    '''
617
        @brief      Init Original/Connection points
618
        @author     Jeongwoo
619
        @date       2018.06.11
620
    '''
621
    def initOriginalAndConnectionPoint(self):
622
        self.ui.originalPointLineEdit.setText('')
623
        self.ui.connectionPointList.clear()
624
        
625
    '''
626
        @brief      Rotate image clockwise
627
        @author     Jeongwoo
628
        @date       2018.06.11
629
    '''
630
    def rotateLeftClickEvent(self, event):
631
        self.initOriginalAndConnectionPoint()
632
        self.ui.imageView.command = RotateImageCommand.RotateImageCommand(self.ui.imageView, True)
633
        self.guidelineStateChangedEvent(None)
634
        
635
    '''
636
        @brief      Rotate image counter-clockwise
637
        @author     Jeongwoo
638
        @date       2018.06.11
639
    '''
640
    def rotateRightClickEvent(self, event):
641
        self.initOriginalAndConnectionPoint()
642
        self.ui.imageView.command = RotateImageCommand.RotateImageCommand(self.ui.imageView)
643
        self.guidelineStateChangedEvent(None)
644
        
645
    '''
646
        @brief      Flip image left and right
647
        @author     Jeongwoo
648
        @date       2018.06.11
649
    '''
650
    def flipHorizontalClickEvent(self, event):
651
        self.initOriginalAndConnectionPoint()
652
        self.ui.imageView.command = FlipImageCommand.FlipImageCommand(self.ui.imageView, horizontal = True, vertical = False)
653
        self.guidelineStateChangedEvent(None)
654
        
655
    '''
656
        @brief      Flip image up and down
657
        @author     Jeongwoo
658
        @date       2018.06.11
659
    '''
660
    def flipVerticalClickEvent(self, event):
661
        self.initOriginalAndConnectionPoint()
662
        self.ui.imageView.command = FlipImageCommand.FlipImageCommand(self.ui.imageView, horizontal = False, vertical = True)
663
        self.guidelineStateChangedEvent(None)
664

  
665
    def adjustOriginalPoint(self, adjustX, adjustY):
666
        originalPoint = self.ui.originalPointLineEdit.text()
667
        if originalPoint and self.ui.imageView.isOriginalPointSelected:
668
            x = float(originalPoint.split(",")[0])
669
            y = float(originalPoint.split(",")[1])
670
            OriginalPointCommand.OriginalPointCommand.removeCircle(self.ui.imageView, x, y)
671
            x = x - adjustX
672
            y = y - adjustY
673
            self.ui.originalPointLineEdit.setText(str(x)+","+str(y))
674
            OriginalPointCommand.OriginalPointCommand.drawCircle(self.ui.imageView, x, y)
675

  
676
    def adjustConnectionPoint(self, adjustX, adjustY):
677
        itemCount = self.ui.connectionPointList.count()
678
        for index in range(itemCount):
679
            item = self.ui.connectionPointList.item(index)
680
            text = item.text()
681
            x = float(text.split(",")[0])
682
            y = float(text.split(",")[1])
683
            self.removeConnectionPointCircle(QtCore.QPointF(x, y))
684
            x = x - adjustX
685
            y = y - adjustY
686
            item.setText(str(x)+","+str(y))
687
            ConnectionPointCommand.ConnectionPointCommand.drawCircle(self.ui.imageView, x, y)
688
                         
689
    '''
690
        @brief  Validation Check
691
        @return (isValid, errorMsg)
692
        @history    2018.05.03  Jeongwoo    Change self.dbHelper to AppDocData
693
    '''
694
    def isValidSymbolInfo(self):
695
        print("isValid")
696
        EXCEPTION_MSG_FORMAT = "{} 입력을 확인해주세요."
697
        EXCEPTION_MSG_DUPLICATED_FORMAT = "이미 저장된 {} 값입니다."
698
        infoTitle = ""
699

  
700
        #idText = self.ui.idLineEdit.text()
701
        '''
702
            id = int(idText) if idText else -1
703
            if (id == -1 or id < 100):
704
                infoTitle = self.ui.idLabel.text()
705
                return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
706
        '''
707

  
708
        '''
709
            lastId = -1
710
            if self.selectedSymbol is not None:
711
                lastId = self.selectedSymbol.getId()
712
            if lastId != id and AppDocData.instance().isExistData('symId', id):
713
                infoTitle = self.ui.idLabel.text()
714
                return (False, EXCEPTION_MSG_DUPLICATED_FORMAT.format(infoTitle))
715
        '''
716

  
717
        if not self.ui.nameLineEdit.text():
718
            infoTitle = self.ui.nameLabel.text()
719
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
720

  
721
        thresholdText = self.ui.thresholdLineEdit.text()
722
        threshold = float(thresholdText) if thresholdText else -1
723
        if not(threshold >= 0 and threshold <= 100):
724
            infoTitle = self.ui.thresholdLabel.text()
725
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
726
            
727
        minMatchPointText = self.ui.minMatchPointLineEdit.text()
728
        minMatchPoint = float(minMatchPointText) if minMatchPointText else -1
729
        if not(minMatchPoint >= 0):
730
            infoTitle = self.ui.minMatchPointLabel.text()
731
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
732

  
733
        if self.ui.typeComboBox.currentIndex() == 0:
734
            infoTitle = self.ui.typeLabel.text()
735
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
736

  
737
        if self.ui.baseSymbolComboBox.currentIndex() == 0: #default value(None) index
738
            infoTitle = self.ui.baseSymbolLabel.text()
739
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
740

  
741
        #Additional Symbol is Nullable
742

  
743
        if not self.ui.originalPointLineEdit.text() or self.ui.imageView.isOriginalPointSelected == False:
744
            infoTitle = self.ui.originalPointLabel.text()
745
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
746

  
747
        if not (self.ui.connectionPointList.count() > 0):
748
            infoTitle = self.ui.connectionPointLabel.text()
749
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
750
            
751
        return True, None
752

  
753
    '''
754
        @brief  Slot for change offsets
755
        @author Jeongwoo
756
        @date   2018.05.02
757
        @history    2018.06.11  Jeongwoo    Add refresh guideline
758
    '''
759
    @pyqtSlot(float, float)
760
    def offsetChanged(self, oX, oY):
761
        print('offsetX : ' + str(self.offsetX) + '->' + str(self.offsetX+oX))
762
        print('offsetY : ' + str(self.offsetY) + '->' + str(self.offsetY+oY))
763
        self.offsetX = self.offsetX + oX
764
        self.offsetY = self.offsetY + oY
765
        self.guidelineStateChangedEvent(None)
DTI_PID/DTI_PID/QtImageViewer.py
274 274

  
275 275
        QGraphicsView.mouseMoveEvent(self, event)
276 276

  
277
    '''
278
        @brief      
279
        @author     
280
        @date       
281
        @history    block clear selection when right mouse button is clicked
282
    '''
277 283
    def mousePressEvent(self, event):
278
        """ Start mouse pan or zoom mode.
279
        """
280
        
281 284
        try:
282 285
            if self.command is not None:
283 286
                scenePos = self.mapToScene(event.pos())
......
286 289
        except Exception as ex:
287 290
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
288 291

  
289
        QGraphicsView.mousePressEvent(self, event)
292
        if event.button() != Qt.RightButton:
293
            QGraphicsView.mousePressEvent(self, event)
290 294

  
291 295
    def mouseReleaseEvent(self, event):
292 296
        """ Stop mouse pan or zoom mode (apply zoom if valid).
......
322 326
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
323 327

  
324 328
        QGraphicsView.mouseReleaseEvent(self, event)
325
        self.mainWindow.refreshResultPropertyTableWidget()
329
        #self.mainWindow.refreshResultPropertyTableWidget()
326 330

  
327 331
    def mouseDoubleClickEvent(self, event):
328 332
        """ Show entire image.
DTI_PID/DTI_PID/READ ME.txt
98 98
- ���� ������� ��ϵ� �ɺ� �̹��� ����Ʈ�� Tree �������� ǥ��
99 99
- �ɺ��� ������� ���콺 ���� Ŭ���� ��� [����, ũ�Ժ���, ����] �� ������ Context Menu ǥ��
100 100
- ��µǴ� �ɺ� �̹����� Symbol Type �� ���� Tree ����
101
- �ɺ��� ������� ���� Ŭ�� �� QSymbolEditorDialog ǥ��
101
- �ɺ��� ������� ���� Ŭ�� �� SymbolEditorDialog ǥ��
102 102
- �ɺ��� ������� Ŭ�� �� �ϴ� QPropertyTableWidget �� �ɺ� ���� ���
103 103
- �ɺ� �巡��, ��� �� QtImageViewer �� �ɺ� ����
104 104

  
......
132 132
- SymbolTreeWidget ���� �ɺ� ������� ���콺 ��Ŭ���� �� �޴� ���� �� ��µǴ� ���̾�α�
133 133
- �ܼ��� �ɺ� �̹����� ���
134 134

  
135
18) QSymbolEditorDialog.py
135
18) SymbolEditorDialog.py
136 136
- ���⿡ ����� �ɺ��� ���, �����ϱ� ���� ���̾�α�
137 137
- ���� ������ ���� ��ư Ŭ�� �� ���� ��ü�� ����� ä�� ���̾�α� ���
138 138
- Hand, Crop, Pen, Eraser, Area Eraser, Fit Image, Remove Text, Rotation, Flip, Zoom, Show Guideline �޴��� ����
DTI_PID/DTI_PID/Shapes/EngineeringLineItem.py
448 448
        startPt = self.startPoint() 
449 449
        endPt = self.endPoint()
450 450

  
451
        if issubclass(type(obj), SymbolSvgItem):
452
            for i in range(len(obj.connectors)):
453
                pt = obj.connectors[i].sceneConnectPoint
454

  
455
                if (self.connectors[0].connectedItem is None) and (Point(startPt[0], startPt[1]).distance(Point(pt[0], pt[1])) < toler):
456
                    self.connectors[0].connectedItem = obj 
457
                    obj.connectors[i].connectedItem = self
451
        try:
452
            if issubclass(type(obj), SymbolSvgItem):
453
                for i in range(len(obj.connectors)):
454
                    pt = obj.connectors[i].sceneConnectPoint
455

  
456
                    if (self.connectors[0].connectedItem is None) and (Point(startPt[0], startPt[1]).distance(Point(pt[0], pt[1])) < toler):
457
                        self.connectors[0].connectedItem = obj 
458
                        obj.connectors[i].connectedItem = self
459
                        res.append(obj)
460
                    if (self.connectors[1].connectedItem is None) and (Point(endPt[0], endPt[1]).distance(Point(pt[0], pt[1])) < toler):
461
                        self.connectors[1].connectedItem = obj
462
                        obj.connectors[i].connectedItem = self
463
                        res.append(obj)
464
            elif type(obj) is QEngineeringLineItem:
465
                _startPt = obj.startPoint()
466
                _endPt = obj.endPoint()
467
                if((Point(startPt[0], startPt[1]).distance(Point(_startPt[0], _startPt[1])) < toler)):
468
                    self.connectors[0].connectedItem = obj
469
                    obj.connectors[0].connectedItem = self
470
                    res.append(obj)
471
                if ((Point(startPt[0], startPt[1]).distance(Point(_endPt[0], _endPt[1])) < toler)):
472
                    self.connectors[0].connectedItem = obj
473
                    obj.connectors[1].connectedItem = self
458 474
                    res.append(obj)
459
                if (self.connectors[1].connectedItem is None) and (Point(endPt[0], endPt[1]).distance(Point(pt[0], pt[1])) < toler):
475
                
476
                if((Point(endPt[0], endPt[1]).distance(Point(_startPt[0], _startPt[1])) < toler)):
460 477
                    self.connectors[1].connectedItem = obj
461
                    obj.connectors[i].connectedItem = self
478
                    obj.connectors[0].connectedItem = self
462 479
                    res.append(obj)
463
        elif type(obj) is QEngineeringLineItem:
464
            _startPt = obj.startPoint()
465
            _endPt = obj.endPoint()
466
            if((Point(startPt[0], startPt[1]).distance(Point(_startPt[0], _startPt[1])) < toler)):
467
                self.connectors[0].connectedItem = obj
468
                obj.connectors[0].connectedItem = self
469
                res.append(obj)
470
            if ((Point(startPt[0], startPt[1]).distance(Point(_endPt[0], _endPt[1])) < toler)):
471
                self.connectors[0].connectedItem = obj
472
                obj.connectors[1].connectedItem = self
473
                res.append(obj)
474
            
475
            if((Point(endPt[0], endPt[1]).distance(Point(_startPt[0], _startPt[1])) < toler)):
476
                self.connectors[1].connectedItem = obj
477
                obj.connectors[0].connectedItem = self
478
                res.append(obj)
479
            
480
            if ((Point(endPt[0], endPt[1]).distance(Point(_endPt[0], _endPt[1])) < toler)):
481
                self.connectors[1].connectedItem = obj
482
                obj.connectors[1].connectedItem = self
483
                res.append(obj)
480
                
481
                if ((Point(endPt[0], endPt[1]).distance(Point(_endPt[0], _endPt[1])) < toler)):
482
                    self.connectors[1].connectedItem = obj
483
                    obj.connectors[1].connectedItem = self
484
                    res.append(obj)
485
        except Exception as ex:
486
            from App import App 
487

  
488
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
489
            App.mainWnd().addMessage(MessageType.Error, message)
484 490

  
485 491
        return res
486 492

  
DTI_PID/DTI_PID/Shapes/EngineeringUnknownItem.py
1
# coding: utf-8
2
import os.path
3
import copy
4
import sys
5
try:
6
    from PyQt5.QtCore import *
7
    from PyQt5.QtGui import *
8
    from PyQt5.QtWidgets import *
9
except ImportError:
10
    try:
11
        from PyQt4.QtCore import *
12
        from PyQt4.QtGui import *
13
    except ImportError:
14
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
15

  
16
from EngineeringPolylineItem import QEngineeringPolylineItem
17
from QGraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
18
from AppDocData import AppDocData
19
from QEngineeringAbstractItem import QEngineeringAbstractItem
20

  
21
class QEngineeringUnknownItem(QEngineeringPolylineItem, QEngineeringAbstractItem):
22
    '''
23
        @history    2018.06.18  Jeongwoo    Add variable [transfer] for pyqtSignal
24
    '''
25
    def __init__(self, pts, parent=None):
26
        import uuid
27

  
28
        QEngineeringPolylineItem.__init__(self, parent)
29
        QEngineeringAbstractItem.__init__(self)
30

  
31
        self.uid = uuid.uuid4() # generate UUID
32
        self.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable)
33
        self.setAcceptHoverEvents(True)
34
        self.setAcceptTouchEvents(True)
35

  
36
        for pt in pts:
37
            self._pol.append(QPointF(pt[0], pt[1]))
38
        self._pol.append(QPointF(pts[0][0], pts[0][1])) # close path
39
        self.buildItem()
40
        
41
    '''
42
        @build  build path
43
        @author humkyung
44
        @date   2018.07.06
45
    '''
46
    def buildItem(self):
47
        super(QEngineeringUnknownItem, self).buildItem()
48

  
49
        self.setPen(QPen(Qt.red, 1, Qt.DashDotLine))
50
        self.setBrush(QBrush(QColor(255, 255, 0, 127)))
51

  
52
    def hoverEnterEvent(self, event):
53
        pass
54

  
55
    def hoverLeaveEvent(self, event):
56
        pass
57

  
58
    def hoverMoveEvent(self, event):
59
        pass
60

  
61
    '''
62
        @brief      remove item when user press delete key
63
        @author     humkyung
64
        @date       2018.06.11
65
        @history    2018.06.18  Jeongwoo    Call deleteUnknownItemFromScene method
66
    '''
67
    def keyPressEvent(self, event): 
68
        if event.key() == Qt.Key_Delete:
69
            self.deleteUnknownItemFromScene()
70

  
71
    '''
72
        @brief      show context menu
73
        @author     humkyung
74
        @date       2018.08.08
75
    '''
76
    def contextMenuEvent(self, event):
77
        menu = QMenu()
78
        registerSymbolAction = QAction("심볼 등록")
79
        registerSymbolAction.triggered.connect(lambda: self.onRegisterSymbolEvent())
80
        menu.addAction(registerSymbolAction)
81

  
82
        menu.exec_(event.screenPos())
83

  
84
    '''
85
        @brief  override paint(draw connection points)
86
        @author humkyung
87
        @date   2018.08.08
88
    '''
89
    def paint(self, painter, options=None, widget=None):
90
        if self.isSelected():
91
            self.setBrush(QBrush(QColor(255, 0, 0, 127)))
92
        else:
93
            self.setBrush(QBrush(QColor(255, 255, 0, 127)))
94

  
95
        QEngineeringPolylineItem.paint(self, painter, options, widget)
96

  
97
    '''
98
        @brief      show symbol editor
99
        @author     humkyung
100
        @date       2018.08.08
101
    '''
102
    def onRegisterSymbolEvent(self):
103
        from App import App
104

  
105
        try:
106
            selected = [item for item in self.scene().items() if item.isSelected() and type(item) is QEngineeringUnknownItem]
107
            rect = QRectF()
108
            for item in selected:
109
                rect = rect.united(item.sceneBoundingRect())
110

  
111
            image = App.mainWnd().onAreaSelected(round(rect.left()), round(rect.top()), round(rect.width()), round(rect.height()))
112
        except Exception as ex:
113
            from App import App 
114

  
115
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
116
            App.mainWnd().addMessage(MessageType.Error, message)
117

  
118
    '''
119
        @brief  parse xml for item
120
        @author humkyung
121
        @date   2018.06.20
122
    '''
123
    @staticmethod 
124
    def fromXml(node):
125
        item = None
126
        try:
127
            location = [float(x) for x in node.find('LOCATION').text.split(',')]
128
            size = [float(x) for x in node.find('SIZE').text.split(',')]
129
            points = [[int(float(coord)) for coord in pt.split(',')] for pt in node.find('POINTS').text.split('\n')]
130

  
131
            item = QEngineeringUnknownItem(points)
132
        except Exception as ex:
133
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
134

  
135
        return item
136

  
137
    '''
138
        @brief      generate xml code
139
        @author     humkyung
140
        @date       2018.06.11
141
        @history    2018.06.14  Jeongwoo    Add LOCATION, SIZE info
142
    '''
143
    def toXml(self, owner = None, name='UNKNOWN'):
144
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree
145
        from EngineeringLineItem import QEngineeringLineItem
146
        from SymbolSvgItem import SymbolSvgItem
147

  
148
        try:
149
            node = Element('UNKNOWN')
150
            
151
            rect = self.sceneBoundingRect()
152
            locNode = Element('LOCATION')
153
            locNode.text = '{},{}'.format(rect.left(), rect.top())
154
            node.append(locNode)
155

  
156
            sizeNode = Element('SIZE')
157
            sizeNode.text = '{},{}'.format(rect.width(), rect.height())
158
            node.append(sizeNode)
159

  
160
            ptNode = Element('POINTS')
161
            points = None
162
            for pt in self._pol:
163
                if points is None:
164
                    points = '{},{}'.format(int(pt.x()), int(pt.y())) 
165
                else:
166
                    points += '\n{},{}'.format(int(pt.x()), int(pt.y()))
167
            ptNode.text = points
168
            node.append(ptNode)
169
        except Exception as ex:
170
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
171
            return str(self.uid)
172

  
173
        return node 
174

  
175
    '''
176
        @brief      Add to Scene
177
        @author     Jeongwoo
178
        @date       2018.06.14
179
    '''
180
    def addUnknownItemToScene(self, scene):
181
        self.setZValue(1.0)
182
        scene.addItem(self)
183

  
184
    '''
185
        @brief      Delete from Scene
186
        @author     Jeongwoo
187
        @date       2018.06.14
188
        @history    2018.06.18  Jeongwoo    Add calling removed signal
189
    '''
190
    def deleteUnknownItemFromScene(self):
191
        self.transfer.onRemoved.emit(self)
192
        self.scene().removeItem(self)
193

  
194
    def boundingRectOnScene(self):
195
        rect = self.sceneBoundingRect()
196
        return rect
DTI_PID/DTI_PID/Shapes/QEngineeringUnknownItem.py
1
# coding: utf-8
2
import os.path
3
import copy
4
import sys
5
try:
6
    from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect, QObject
7
    from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont, QColor
8
    from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem
9
except ImportError:
10
    try:
11
        from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect, QObject
12
        from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont, QColor
13
    except ImportError:
14
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
15

  
16
from EngineeringPolylineItem import QEngineeringPolylineItem
17
from QGraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
18
from AppDocData import AppDocData
19
from QEngineeringAbstractItem import QEngineeringAbstractItem
20

  
21
class QEngineeringUnknownItem(QEngineeringPolylineItem, QEngineeringAbstractItem):
22
    '''
23
        @history    2018.06.18  Jeongwoo    Add variable [transfer] for pyqtSignal
24
    '''
25
    def __init__(self, pts, parent=None):
26
        import uuid
27

  
28
        QEngineeringPolylineItem.__init__(self, parent)
29
        QEngineeringAbstractItem.__init__(self)
30

  
31
        self.uid = uuid.uuid4() # generate UUID
32
        self.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable)
33
        self.setAcceptHoverEvents(True)
34
        self.setAcceptTouchEvents(True)
35

  
36
        for pt in pts:
37
            self._pol.append(QPointF(pt[0], pt[1]))
38
        self._pol.append(QPointF(pts[0][0], pts[0][1])) # close path
39
        self.buildItem()
40
        
41
    '''
42
        @build  build path
43
        @author humkyung
44
        @date   2018.07.06
45
    '''
46
    def buildItem(self):
47
        super(QEngineeringUnknownItem, self).buildItem()
48

  
49
        self.setPen(QPen(Qt.red, 1, Qt.DashDotLine))
50
        self.setBrush(QBrush(QColor(255, 255, 0, 127)))
51

  
52
    def hoverEnterEvent(self, event):
53
        pass
54

  
55
    def hoverLeaveEvent(self, event):
56
        pass
57

  
58
    def hoverMoveEvent(self, event):
59
        pass
60

  
61
    '''
62
        @brief      remove item when user press delete key
63
        @author     humkyung
64
        @date       2018.06.11
65
        @history    2018.06.18  Jeongwoo    Call deleteUnknownItemFromScene method
66
    '''
67
    def keyPressEvent(self, event): 
68
        if event.key() == Qt.Key_Delete:
69
            self.deleteUnknownItemFromScene()
70

  
71
    '''
72
        @brief  parse xml for item
73
        @author humkyung
74
        @date   2018.06.20
75
    '''
76
    @staticmethod 
77
    def fromXml(node):
78
        item = None
79
        try:
80
            location = [float(x) for x in node.find('LOCATION').text.split(',')]
81
            size = [float(x) for x in node.find('SIZE').text.split(',')]
82
            points = [[int(float(coord)) for coord in pt.split(',')] for pt in node.find('POINTS').text.split('\n')]
83

  
84
            item = QEngineeringUnknownItem(points)
85
        except Exception as ex:
86
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
87

  
88
        return item
89

  
90
    '''
91
        @brief      generate xml code
92
        @author     humkyung
93
        @date       2018.06.11
94
        @history    2018.06.14  Jeongwoo    Add LOCATION, SIZE info
95
    '''
96
    def toXml(self, owner = None, name='UNKNOWN'):
97
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree
98
        from EngineeringLineItem import QEngineeringLineItem
99
        from SymbolSvgItem import SymbolSvgItem
100

  
101
        try:
102
            node = Element('UNKNOWN')
103
            
104
            rect = self.sceneBoundingRect()
105
            locNode = Element('LOCATION')
106
            locNode.text = '{},{}'.format(rect.left(), rect.top())
107
            node.append(locNode)
108

  
109
            sizeNode = Element('SIZE')
110
            sizeNode.text = '{},{}'.format(rect.width(), rect.height())
111
            node.append(sizeNode)
112

  
113
            ptNode = Element('POINTS')
114
            points = None
115
            for pt in self._pol:
116
                if points is None:
117
                    points = '{},{}'.format(int(pt.x()), int(pt.y())) 
118
                else:
119
                    points += '\n{},{}'.format(int(pt.x()), int(pt.y()))
120
            ptNode.text = points
121
            node.append(ptNode)
122
        except Exception as ex:
123
            return str(self.uid)
124
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
125

  
126
        return node 
127

  
128
    '''
129
        @brief      Add to Scene
130
        @author     Jeongwoo
131
        @date       2018.06.14
132
    '''
133
    def addUnknownItemToScene(self, scene):
134
        self.setZValue(1.0)
135
        scene.addItem(self)
136

  
137
    '''
138
        @brief      Delete from Scene
139
        @author     Jeongwoo
140
        @date       2018.06.14
141
        @history    2018.06.18  Jeongwoo    Add calling removed signal
142
    '''
143
    def deleteUnknownItemFromScene(self):
144
        self.transfer.onRemoved.emit(self)
145
        self.scene().removeItem(self)
146

  
147
    def boundingRectOnScene(self):
148
        rect = self.sceneBoundingRect()
149
        return rect
DTI_PID/DTI_PID/SymbolEditorDialog.py
1
# coding: utf-8
2
from PyQt5 import QtCore, QtGui, QtWidgets
3
from PyQt5.QtCore import pyqtSlot, QRectF
4
from PyQt5.QtWidgets import *
5
from PyQt5.QtGui import *
6
from QtImageViewer import QtImageViewer
7
import os
8
import sqlite3
9
import sys
10
import symbol, SymbolBase
11
import potrace
12
import numpy as np
13
import cv2
14

  
15
import SymbolEditor_UI
16
from AppDocData import AppDocData
17

  
18
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
19
import CropCommand, HandCommand, ZoomCommand, PenCommand, EraserCommand, AreaEraserCommand, OriginalPointCommand, ConnectionPointCommand, AreaZoomCommand, FitImageCommand, RemoveTextCommand, RotateImageCommand, FlipImageCommand
20

  
21

  
22
class QSymbolEditorDialog(QDialog):
23
    FILE_NUMBER = 0
24

  
25
    '''
26
        @history    2018.05.02  Jeongwoo    Add variables (self.offsetX, self.offsetY, self.newSym)
27
                    2018.05.03  Jeongwoo    Remove parameter in SG_DbHelper()
28
                                            Remove self.dbHelper variable
29
                    2018.07.03  Yecheol     Rename File, Is Instrument Label added
30
    '''
31
    def __init__(self, parent, image, project, selectedSymbol = None):
32
        QDialog.__init__(self, parent)
33

  
34
        try:
35
            self.image = image
36
            self.selectedSymbol = selectedSymbol
37
            self.project = project
38
            self.ui = SymbolEditor_UI.Ui_Dialog()
39
            self.ui.setupUi(self)
40
            self.setupImageViewer()
41
            self.setupTools()
42
            self.initForms()
43
            self.initContents()
44
            self.isAccepted = False
45
            self.offsetX = 0
46
            self.offsetY = 0
47
            self.newSym = None
48

  
49
            self.setWindowTitle('심볼 편집기')
50
        except Exception as ex:
51
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
52

  
53
    def convertQImageToMat(self, incomingImage):
54
        '''  Converts a QImage into an opencv MAT format  '''
55

  
56
        try:
57
            incomingImage = incomingImage.convertToFormat(QImage.Format_RGBA8888)
58

  
59
            width = incomingImage.width()
60
            height = incomingImage.height()
61

  
62
            ptr = incomingImage.bits()
63
            ptr.setsize(incomingImage.byteCount())
64
            arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
65
            return arr
66
        except Exception as ex:
67
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
68

  
69
    '''
70
        @brief  Set up QtImageViewer and QImage
71
        @history    2018.05.02  Jeongwoo    Connect imageviewer and QSymbolEditorDialog
72
    '''
73
    def setupImageViewer(self):
74
        from MainWindow import MainWindow
75

  
76
        x = self.ui.imageViewContainer.x()
77
        y = self.ui.imageViewContainer.y()
78
        width = self.ui.imageViewContainer.frameGeometry().width()
79
        height = self.ui.imageViewContainer.frameGeometry().height()
80
        self.ui.imageView = QtImageViewer(MainWindow.instance())
81
        self.ui.imageView.setGeometry(QtCore.QRect(0, y, height, height))
82
        self.ui.imageView.aspectRatioMode = QtCore.Qt.KeepAspectRatio
83
        self.ui.imageView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
84
        self.ui.imageView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
... 이 차이점은 표시할 수 있는 최대 줄수를 초과해서 이 차이점은 잘렸습니다.

내보내기 Unified diff