프로젝트

일반

사용자정보

개정판 c4e44066

IDc4e440669a3b55c1682dcda145f5fda2e2fe20ab
상위 7abebdd1
하위 19bc0ecc

예철 임 이(가) 6년 이상 전에 추가함

file added : QSymbolEditorDialog.py

차이점 보기:

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

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

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

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

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

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

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

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

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

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

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

  
303
        convertedThreshold = int(threshold) / 100.0
304

  
305
        self.newSym = symbol.SymbolBase(int(symId), fileName, type, convertedThreshold, int(minMatchPoint), True, 
306
                        rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid)
307

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

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

  
380
                        image.save(imagePath, 'PNG')
381

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

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

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

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

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

  
437
        AppDocData.instance().updateSymbol(self.selectedSymbol)
438

  
439
    '''
440
        @history    2018.06.12  Jeongwoo    coords type changed (int → float)
441
    '''
442
    def keyPressEvent(self, event):
443
        if event.key() == QtCore.Qt.Key_Delete:
444
            if self.ui.connectionPointList.hasFocus():
445
                selectedItems = self.ui.connectionPointList.selectedItems()
446
                if selectedItems is not None:
447
                    for item in selectedItems:
448
                        text = item.text()
449
                        x = float(text.split(",")[0])
450
                        y = float(text.split(",")[1])
451
                        self.removeConnectionPointCircle(QtCore.QPointF(x, y))
452
                        self.ui.connectionPointList.takeItem(self.ui.connectionPointList.row(item))
453
            elif self.ui.additionalSymbolListWidget.hasFocus():
454
                selectedItems = self.ui.additionalSymbolListWidget.selectedItems()
455
                if selectedItems is not None:
456
                    for item in selectedItems:
457
                        self.ui.additionalSymbolListWidget.takeItem(self.ui.additionalSymbolListWidget.row(item))
458
                        
459
    '''
460
        @brief  Hand Tool Button Clicked
461
    '''
462
    def handToolClickEvent(self, event):
463
        print("hand tool clicked")
464
        self.ui.imageView.command = HandCommand.HandCommand(self.ui.imageView)
465
        
466
    '''
467
        @brief  Crop Tool Button Clicked
468
        @history    2018.06.11  Jeongwoo    init original/connection points and guide line refresh
469
    '''
470
    def cropToolClickEvent(self, event):
471
        print("crop tool clicked")
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
        print("area eraser")
537
        self.ui.imageView.command = AreaEraserCommand.AreaEraserCommand(self.ui.imageView)
538
                             
539
    '''
540
        @brief  Fit Image Tool Button Clicked
541
        @history    2018.05.02  Jeongwoo    Method name changed(getAdjust → getOffset)
542
                                            Emit offsets to startPointChanged
543
                    2018.06.11  Jeongwoo    init original/connection points
544
    '''
545
    def fitImageToolClickEvent(self, event):
546
        print("Fit Image")
547
        self.initOriginalAndConnectionPoint()
548
        self.ui.imageView.command = FitImageCommand.FitImageCommand(self.ui.imageView)
549
        adjustX, adjustY = self.ui.imageView.command.getOffset()
550
        #self.adjustOriginalPoint(adjustX, adjustY)
551
        #self.adjustConnectionPoint(adjustX, adjustY)
552
        self.ui.imageView.startPointChanged.emit(adjustX, adjustY)
553
                         
554
    '''
555
        @brief  Guideline Check State Changed
556
    '''
557
    def guidelineStateChangedEvent(self, value):
558
        if self.ui.guidelineCheckbox.isChecked():
559
            self.ui.imageView.showGuideline(True)
560
        else:
561
            self.ui.imageView.showGuideline(False)
562
                             
563
    '''
564
        @brief  Add AdditionalSymbol String on ListWidget Listener
565
    '''
566
    def addAdditionalSymbolEvent(self, event):
567
        print("addAdditionalSymbolEvent")
568
        additionalSymbolIndex = self.ui.additionalSymbolComboBox.currentIndex()
569
        if additionalSymbolIndex != 0:
570
            print("Symbol Selected")
571
            direction = self.ui.defaultSymbolDirectionComboBox.currentText()
572
            symbolName = self.ui.additionalSymbolComboBox.currentText()
573
            self.addAdditionalSymbol(direction, symbolName)
574
                    
575
    '''
576
        @brief  Add AdditionalSymbol String on ListWidget
577
    '''
578
    def addAdditionalSymbol(self, direction, symbolName):
579
        text = "{},{}".format(direction, symbolName)
580

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

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

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

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

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

  
704
        idText = self.ui.idLineEdit.text()
705
        id = int(idText) if idText else -1
706
        if (id == -1 or id < 100):
707
            infoTitle = self.ui.idLabel.text()
708
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
709

  
710
        lastId = -1
711
        if self.selectedSymbol is not None:
712
            lastId = self.selectedSymbol.getId()
713
        if lastId != id and AppDocData.instance().isExistData('symId', id):
714
            infoTitle = self.ui.idLabel.text()
715
            return (False, EXCEPTION_MSG_DUPLICATED_FORMAT.format(infoTitle))
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)

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)