프로젝트

일반

사용자정보

개정판 b1a510c6

IDb1a510c67d2d5838a9a11da439bff8570ff49410
상위 b3fb20bd
하위 fb3664ad

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

issue #646: 심볼 라이브러리 불러오기,내보내기 기능 추가

Change-Id: I3dc37a80eeef6afa97f0a9e5345ae9b9fdba3cfa

차이점 보기:

App.spec
12 12
	('.\\DTI_PID\\DTI_PID\\*.pdf', '.'),
13 13
	('.\\*.BMP', '.'),
14 14
	('.\\DTI_PID\\DTI_PID\\db\\*.db', 'db'),
15
	('.\\DTI_PID\\DTI_PID\\db\\*.syl', 'db')
15 16
	('.\\DTI_PID\\DTI_PID\\translate\\*.qm', 'translate'),
16 17
	('.\\DTI_PID\\DTI_PID\\Scripts\\*.sql', 'Scripts'),
17 18
	('.\\DTI_PID\\DTI_PID\\Scripts\\MSSQL\\*.sql', 'Scripts\\MSSQL'),
DTI_PID/DTI_PID/AppDocData.py
284 284
        templateDbPath = os.path.join(path, 'Template.db')
285 285
        return templateDbPath
286 286

  
287
    def get_template_symbol_library_path(self):
288
        """return template symbol library path"""
289

  
290
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
291
        return os.path.join(path, 'SymbolLibrary.syl')
292

  
287 293
    def getAppDbPath(self):
288 294
        """
289 295
        @brief      Get application DB file path in ProgramData
......
307 313

  
308 314
        if self._colors is None or self._colors == []:
309 315
            self._colors = []
310
            conn = self.project.database.connect()
311
            with conn:
316
            with self.project.database.connect() as conn:
312 317
                try:
313 318
                    cursor = conn.cursor()
314 319
                    sql = 'SELECT UID,RED,GREEN,BLUE FROM Colors'
......
1658 1663
        else:
1659 1664
            self._symbolBase[fieldName] = {}
1660 1665

  
1661
        conn = self.project.database.connect()
1662
        with conn:
1666
        with self.project.database.connect() as conn:
1663 1667
            cursor = conn.cursor()
1664 1668
            sql = self.project.database.to_sql("""SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,
1665 1669
                        a.BaseSymbol,a.AdditionalSymbol,a.IsExceptDetect,a.HasInstrumentLabel,a.flip FROM Symbol a inner join SymbolType b on a.SymbolType_UID=b.UID WHERE """ + "a." + fieldName + '=?')
......
1971 1975

  
1972 1976
        return False
1973 1977

  
1978
    def read_symbol_shape(self, symbol_name):
1979
        """read symbol shape(image and svg)"""
1980

  
1981
        res = None
1982

  
1983
        with self.project.database.connect() as conn:
1984
            try:
1985
                # Get a cursor object
1986
                cursor = conn.cursor()
1987

  
1988
                sql = f"select Image,Svg from Symbol where Name='{symbol_name}'"
1989
                cursor.execute(sql)
1990
                records = cursor.fetchall()
1991
                for record in records:
1992
                    res = (record[0], record[1])
1993
                    break
1994

  
1995
            # Catch the exception
1996
            except Exception as ex:
1997
                from App import App
1998
                # Roll back any change if something goes wrong
1999
                conn.rollback()
2000

  
2001
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
2002
                                                               sys.exc_info()[-1].tb_lineno)
2003
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2004

  
2005
        return res
2006

  
2007

  
2008
    def update_symbol_shape(self, symbol, image_file, svg_file):
2009
        """update symbol shape"""
2010

  
2011
        with self.project.database.connect() as conn:
2012
            try:
2013
                # Get a cursor object
2014
                cursor = conn.cursor()
2015

  
2016
                cols = []
2017
                params = []
2018

  
2019
                image_blob_data = None
2020
                if image_file and os.path.isfile(image_file):
2021
                    with open(image_file, 'rb') as file:
2022
                        image_blob_data = file.read()
2023
                    cols.append('Image=?')
2024
                    params.append(image_blob_data)
2025

  
2026
                svg_blob_data = None
2027
                if svg_file and os.path.isfile(svg_file):
2028
                    with open(svg_file, 'rb') as file:
2029
                        svg_blob_data = file.read()
2030
                    cols.append('Svg=?')
2031
                    params.append(svg_blob_data)
2032

  
2033
                sql = f"update Symbol set {','.join(cols)} where UID={symbol}"
2034
                # Convert data into tuple format
2035
                cursor.execute(sql, tuple(params))
2036
                conn.commit()
2037

  
2038
            # Catch the exception
2039
            except Exception as ex:
2040
                from App import App
2041
                # Roll back any change if something goes wrong
2042
                conn.rollback()
2043

  
2044
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
2045
                                                               sys.exc_info()[-1].tb_lineno)
2046
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2047

  
1974 2048
    '''
1975 2049
        @brief      get Symbol Attribute
1976 2050
        @author     kyouho
DTI_PID/DTI_PID/DetectSymbolDialog.py
21 21
from AppDocData import AppDocData
22 22
import DetectSymbol_UI
23 23

  
24

  
24 25
class QDetectSymbolDialog(QDialog):
25 26

  
26 27
    def __init__(self, parent):
......
28 29
        self.parent = parent
29 30
        self.ui = DetectSymbol_UI.Ui_DetectSymbolDialog()
30 31
        self.ui.setupUi(self)
32
        self.ui.pushButtonImportSymbolLibrary.clicked.connect(self.import_symbol_library)
33
        self.ui.pushButtonExportSymbolLibrary.clicked.connect(self.export_symbol_library)
31 34

  
32 35
        self.table = self.ui.tableWidgetSymbol
33 36
        self.currentRow = 0
34 37
        self.currentColumn = 0
35 38

  
36
        ## box dir setting
37
        self.boxDir = AppDocData.instance().getCurrentProject().path + '/box/'
39
        # box dir setting
40
        self.boxDir = os.path.join(AppDocData.instance().getCurrentProject().path, 'box')
38 41
        if not os.path.exists(self.boxDir):
39 42
            os.makedirs(self.boxDir)
40
        ## drawing file setting
41
        self.drawingDir = AppDocData.instance().getCurrentProject().path + '/drawings/'
43
        # drawing file setting
44
        self.drawingDir = os.path.join(AppDocData.instance().getCurrentProject().path, 'drawings')
42 45
        if os.path.exists(self.drawingDir):
43 46
            files = os.listdir(self.drawingDir)
44 47
            for file in files:
......
63 66
        @author kyouho
64 67
        @date   2018.10.01
65 68
    '''
69

  
66 70
    def currentCellChangedEvent(self, currentRow, currentColumn, previousRow, previousColumn):
67 71
        currentItem = self.table.cellWidget(currentRow, currentColumn)
68 72
        if currentItem is not None:
......
77 81
        @author kyouho
78 82
        @date   2018.10.01
79 83
    '''
84

  
80 85
    def cellDoubleClickedEvent(self, row, column):
81
        cell = self.table.cellWidget(row,column)
86
        cell = self.table.cellWidget(row, column)
82 87
        if cell is not None:
83 88
            import SymbolEditorDialog
84
            symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, cell.pixmap(), AppDocData.instance().getCurrentProject())
89
            symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, cell.pixmap(),
90
                                                                        AppDocData.instance().getCurrentProject())
85 91
            (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
86 92
            if isAccepted:
87 93
                self.table.removeCellWidget(row, column)
......
93 99
        @author kyouho
94 100
        @date   2018.09.18
95 101
    '''
102

  
96 103
    def currentTextChangedEvent(self, text):
97 104
        self.imageName = text
98 105
        self.imgPath = self.drawingDir + self.ui.listWidgetDrawings.currentItem().data(32)
......
103 110
        @author kyouho
104 111
        @date   2018.10.11
105 112
    '''
113

  
106 114
    def setAllSymbolsTable(self):
107 115
        table = self.ui.tableWidgetAllSymbols
108 116
        table.setRowCount(0)
......
130 138
        @author kyouho
131 139
        @date   2018.10.11
132 140
    '''
141

  
133 142
    def findFiles(self, dir, list):
134 143
        fileList = os.listdir(dir)
135 144
        for file in fileList:
......
139 148
            elif os.path.splitext(path)[1] == '.png':
140 149
                list.append(path)
141 150

  
151
    def import_symbol_library(self):
152
        """import symbol library"""
153

  
154
        options = QFileDialog.Options()
155
        options |= QFileDialog.DontUseNativeDialog
156
        name, _ = QFileDialog.getOpenFileName(self, self.tr('Import symbol library'), os.getcwd(), "syl files(*.syl)",
157
                                              options=options)
158
        if not name: return
159

  
160
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
161
        try:
162
            app_doc_data = AppDocData.instance()
163
            name_without_ext, ext = os.path.splitext(name)
164
            symbol_library = name if ext and ext.upper() == '.SYL' else name + '.syl'
165

  
166
            with sqlite3.connect(symbol_library, isolation_level=None) as conn:
167
                conn.row_factory = sqlite3.Row
168
                cursor = conn.cursor()
169
                with app_doc_data.project.database.connect() as target_conn:
170
                    target_cursor = target_conn.cursor()
171
                    if app_doc_data.project.database.db_type == 'SQLite':
172
                        target_conn.execute('PRAGMA foreign_keys = ON')
173
                        target_cursor.execute('begin')
174

  
175
                    tables = ['SymbolType', 'SymbolName', 'SymbolAttribute', 'Symbol']
176

  
177
                    for table in reversed(tables):
178
                        target_cursor.execute(f"delete from {table}")
179

  
180
                    for table in tables:
181
                        sql = f"select * from {table}"
182
                        cursor.execute(sql)
183
                        rows = cursor.fetchall()
184
                        for row in rows:
185
                            cols = ','.join(['?' for item in row])
186
                            sql = f"insert into {table} values({cols})"
187
                            params = tuple(self.convert_to_params(row))
188
                            target_cursor.execute(sql, params)
189

  
190
                    if app_doc_data.project.database.db_type == 'SQLite':
191
                        target_cursor.execute('commit')
192
                    else:
193
                        target_conn.commit()
194

  
195
            QMessageBox.information(self, self.tr('Information'), self.tr('Successfully import symbol library'))
196
        except Exception as ex:
197
            from App import App
198
            from AppDocData import MessageType
199

  
200
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
201
                                                           sys.exc_info()[-1].tb_lineno)
202
            App.mainWnd().addMessage.emit(MessageType.Error, message)
203
            QMessageBox.warning(self, self.tr('Warning'), message)
204
        finally:
205
            QApplication.restoreOverrideCursor()
206

  
207
    def convert_to_params(self, record):
208
        """convert record to string"""
209
        from datetime import datetime
210

  
211
        res = []
212
        for item in record:
213
            if isinstance(item, type(None)):
214
                res.append(None)
215
            elif isinstance(item, str):
216
                res.append(f"{item}")
217
            elif isinstance(item, datetime):
218
                res.append(f"{str(item)}")
219
            elif isinstance(item, bytes):   # for BLOB
220
                res.append(item)
221
            else:  # for numeric values
222
                res.append(str(item))
223

  
224
        return res
225

  
226
    def export_symbol_library(self):
227
        """export symbol library"""
228
        from shutil import copyfile
229

  
230
        options = QFileDialog.Options()
231
        options |= QFileDialog.DontUseNativeDialog
232
        name, _ = QFileDialog.getSaveFileName(self, self.tr('Export symbol library'), os.getcwd(), "syl files(*.syl)",
233
                                              options=options)
234
        if not name: return
235

  
236
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
237
        try:
238
            app_doc_data = AppDocData.instance()
239
            name_without_ext, ext = os.path.splitext(name)
240
            target = name if ext and ext.upper() == '.SYL' else name + '.syl'
241
            copyfile(app_doc_data.get_template_symbol_library_path(), target)
242

  
243
            with app_doc_data.project.database.connect() as conn:
244
                conn.row_factory = sqlite3.Row
245
                cursor = conn.cursor()
246
                with sqlite3.connect(target, isolation_level=None) as target_conn:
247
                    target_conn.row_factory = sqlite3.Row
248
                    target_cursor = target_conn.cursor()
249
                    target_cursor.execute('begin')
250

  
251
                    tables = ['SymbolType', 'SymbolName', 'SymbolAttribute', 'Symbol']
252
                    for table in tables:
253
                        sql = f"select * from {table}"
254
                        cursor.execute(sql)
255
                        rows = cursor.fetchall()
256
                        for row in rows:
257
                            cols = ','.join(['?' for item in row])
258
                            sql = f"insert into {table} values({cols})"
259
                            params = tuple(self.convert_to_params(row))
260
                            target_cursor.execute(sql, params)
261

  
262
                    target_cursor.execute('commit')
263

  
264
            QMessageBox.information(self, self.tr('Information'), self.tr('Successfully export symbol library'))
265
        except Exception as ex:
266
            from App import App
267
            from AppDocData import MessageType
268

  
269
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
270
                                                           sys.exc_info()[-1].tb_lineno)
271
            App.mainWnd().addMessage.emit(MessageType.Error, message)
272
            QMessageBox.warning(self, self.tr('Warning'), message)
273
        finally:
274
            QApplication.restoreOverrideCursor()
142 275

  
143
    
144 276
    '''
145 277
        @brief  text changed Event
146 278
        @author kyouho
147 279
        @date   2018.09.18
148 280
    '''
281

  
149 282
    def detectSymbol(self):
150 283
        if not self.ui.listWidgetDrawings.count():
151 284
            return
......
155 288
        self.progress.setAutoReset(True)
156 289
        self.progress.setAutoClose(True)
157 290
        self.progress.setMinimum(0)
158
        self.progress.resize(600,100)
291
        self.progress.resize(600, 100)
159 292
        self.progress.setWindowTitle("인식 중...")
160 293
        self.progress.show()
161 294
        self.progress.setMaximum(100)
......
171 304
        ## 흑색 이미지로 변환
172 305
        img = cv2.imread(self.imgPath, 1)
173 306
        imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
174
        
307

  
175 308
        ## 프로젝트의 Drawing Area data
176 309
        area = appDocData.getArea('Drawing')
177 310

  
178 311
        ## area 영역 자른 offset
179
        offset = (area.x, area.y) if area is not None else (0,0)
180
        
312
        offset = (area.x, area.y) if area is not None else (0, 0)
313

  
181 314
        ## 이미지 이진화
182
        thresholdImg = cv2.threshold(imgGray , 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
315
        thresholdImg = cv2.threshold(imgGray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
183 316
        ## 프로젝트의 Area 영역만큼만 자른 이미지
184
        areaImg = thresholdImg[round(area.y):round(area.y+area.height), round(area.x):round(area.x+area.width)]
317
        areaImg = thresholdImg[round(area.y):round(area.y + area.height), round(area.x):round(area.x + area.width)]
185 318

  
186 319
        ## 선제거 전에 먼저 작은 영역 제거
187 320
        ## contours 추출을 위한 색반전
188
        areaImg = cv2.bitwise_not(areaImg) 
321
        areaImg = cv2.bitwise_not(areaImg)
189 322
        ## contours 추출
190 323
        contours, hierarchy = cv2.findContours(areaImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
191 324
        for contour in contours:
192 325
            [x, y, w, h] = cv2.boundingRect(contour)
193 326

  
194
            if (w < 40 or h < 40): 
195
                areaImg[y:y+h,x:x+w] = 0
327
            if (w < 40 or h < 40):
328
                areaImg[y:y + h, x:x + w] = 0
196 329
        ## 다시 색반전
197
        areaImg = cv2.bitwise_not(areaImg) 
330
        areaImg = cv2.bitwise_not(areaImg)
198 331

  
199 332
        ## find lines
200 333
        verticalLineList = []
......
213 346
            p2 = vLine[1]
214 347
            y = p1[1]
215 348
            areaImg[y, p1[0]:p2[0]] = 255
216
        
349

  
217 350
        ## contours 추출을 위한 색반전
218
        areaImg = cv2.bitwise_not(areaImg) 
351
        areaImg = cv2.bitwise_not(areaImg)
219 352
        ## contours 추출
220 353
        recList = self.getContours(areaImg)
221 354

  
......
226 359
        self.tableSetting()
227 360

  
228 361
        self.progress.setValue(self.progress.maximum())
229
    
362

  
230 363
    '''
231 364
        @brief  find lines
232 365
        @author kyouho
233 366
        @date   2018.10.01
234 367
    '''
368

  
235 369
    def findLines(self, areaImg, verticalLineList, horizontalLineList):
236 370

  
237 371
        ## for multiprocessing
......
245 379
        for cpuIndex in range(os.cpu_count()):
246 380
            _queue = Queue()
247 381
            _range = value + jumpValue
248
            if os.cpu_count() -1 == cpuIndex:
382
            if os.cpu_count() - 1 == cpuIndex:
249 383
                _range = areaImg.shape[1]
250 384

  
251 385
            _process = Process(target=isVerticalLineThread, args=(value, _range, areaImg, _queue))
252 386
            _process.daemon = True
253 387
            verticalProcessList.append((_process, _queue))
254 388
            value = value + jumpValue
255
        
389

  
256 390
        ## Set Horizontal Line
257 391
        jumpValue = int(areaImg.shape[0] / os.cpu_count())
258 392
        value = 0
259 393
        for cpuIndex in range(os.cpu_count()):
260 394
            _queue = Queue()
261 395
            _range = value + jumpValue
262
            if os.cpu_count() -1 == cpuIndex:
396
            if os.cpu_count() - 1 == cpuIndex:
263 397
                _range = areaImg.shape[0]
264 398

  
265 399
            _process = Process(target=isHorizontalLineThread, args=(value, _range, areaImg, _queue))
266 400
            _process.daemon = True
267 401
            horizontalProcessList.append((_process, _queue))
268 402
            value = value + jumpValue
269
        
403

  
270 404
        ## set percent
271 405
        progressCount = len(verticalProcessList) + len(horizontalProcessList) + 1
272 406
        percentGage = int(100 / progressCount)
......
305 439
        @author kyouho
306 440
        @date   2018.10.01
307 441
    '''
442

  
308 443
    def getContours(self, areaImg):
309
        
444

  
310 445
        contours, hierarchy = cv2.findContours(areaImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
311 446

  
312 447
        ## RecList 정리
......
315 450
        tempRecList = []
316 451
        for contour in contours:
317 452
            [x, y, w, h] = cv2.boundingRect(contour)
318
            tempRecList.append([x-lineWidth, y-lineWidth, x+w+lineWidth, y+h+lineWidth])
453
            tempRecList.append([x - lineWidth, y - lineWidth, x + w + lineWidth, y + h + lineWidth])
319 454

  
320 455
        ## Overlap Rec 합침
321 456
        while len(tempRecList):
......
325 460
                rec2 = tempRecList[index]
326 461
                if rec1[0] <= rec2[2] and rec1[2] >= rec2[0] and rec1[1] <= rec2[3] and rec1[3] >= rec2[1]:
327 462
                    _temp.append(rec2)
328
            
463

  
329 464
            if len(_temp):
330 465
                x1 = rec1[0]
331 466
                y1 = rec1[1]
......
352 487
        @author kyouho
353 488
        @date   2018.10.01
354 489
    '''
490

  
355 491
    def keyPressEvent(self, event):
356 492
        if event.key() == Qt.Key_Delete and self.currentRow != -1 and self.currentColumn != -1:
357 493
            self.table.removeCellWidget(self.currentRow, self.currentColumn)
358
            
359 494

  
360 495
    '''
361 496
        @brief  box to xml
362 497
        @author kyouho
363 498
        @date   2018.10.01
364 499
    '''
500

  
365 501
    def toXml(self, recList, offset):
366 502
        xml = Element('BOXES')
367 503

  
368 504
        ## to xml
369 505
        for rec in recList:
370 506
            [x1, y1, x2, y2] = rec
371
            w = x2-x1
372
            h = y2-y1
373
            if w < 20 or h < 20: continue
374
            elif w*4<h or h*4<w: continue
507
            w = x2 - x1
508
            h = y2 - y1
509
            if w < 20 or h < 20:
510
                continue
511
            elif w * 4 < h or h * 4 < w:
512
                continue
375 513

  
376 514
            boxElement = Element('BOX')
377
            
515

  
378 516
            xElement = Element('X')
379 517
            xElement.text = str(x1 + offset[0])
380 518
            boxElement.append(xElement)
......
384 522
            boxElement.append(yElement)
385 523

  
386 524
            widthElement = Element('WIDTH')
387
            widthElement.text = str(x2-x1)
525
            widthElement.text = str(x2 - x1)
388 526
            boxElement.append(widthElement)
389 527

  
390 528
            heightElement = Element('HEIGHT')
391
            heightElement.text = str(y2-y1)
529
            heightElement.text = str(y2 - y1)
392 530
            boxElement.append(heightElement)
393 531

  
394 532
            xml.append(boxElement)
......
400 538
        @author kyouho
401 539
        @date   2018.09.18
402 540
    '''
541

  
403 542
    def tableSetting(self):
404 543
        columnCount = 3
405 544
        self.table.setColumnCount(columnCount)
......
431 570
                self.table.setCellWidget(rowIndex, boxCount % columnCount, cell)
432 571

  
433 572
                boxCount = boxCount + 1
434
                
435 573

  
436 574
            self.table.resizeColumnsToContents()
437 575
            self.table.resizeRowsToContents()
438
        
576

  
439 577
    '''
440 578
        @brief  accept
441 579
        @author kyouho
442 580
        @date   2018.10.01
443 581
    '''
582

  
444 583
    def accept(self):
445 584
        columnCount = 3
446 585
        recList = []
......
449 588
                cell = self.table.cellWidget(rowIndex, columnIndex)
450 589
                if cell is not None:
451 590
                    [x, y, w, h] = cell.rect
452
                    recList.append([x, y, x+w, y+h])
591
                    recList.append([x, y, x + w, y + h])
453 592

  
454 593
        self.toXml(recList, (0, 0))
455 594

  
456 595
        QDialog.accept(self)
457 596

  
597

  
458 598
'''
459 599
    @brief  Check Vertical Line using Multiprocessing
460 600
    @author kyouho
461 601
    @date   2018.09.27
462 602
'''
603

  
604

  
463 605
def isVerticalLineThread(start, end, img, _queue):
464 606
    minLineSize = 40
465
    
607

  
466 608
    ## Vertical
467 609
    find = False
468 610
    startY = 0
469 611
    lineList = []
470 612
    for x in range(start, end):
471 613
        for y in range(0, img.shape[0]):
472
            if img[y,x] == 0:
614
            if img[y, x] == 0:
473 615
                if find:
474 616
                    continue
475 617
                else:
......
478 620
            else:
479 621
                if find:
480 622
                    if y - startY > minLineSize:
481
                        lineList.append(((x,startY), (x,y)))
623
                        lineList.append(((x, startY), (x, y)))
482 624
                    find = False
483 625
    _queue.put(lineList)
484 626

  
627

  
485 628
'''
486 629
    @brief  Check Horizontal Line using Multiprocessing
487 630
    @author kyouho
488 631
    @date   2018.09.27
489 632
'''
633

  
634

  
490 635
def isHorizontalLineThread(start, end, img, _queue):
491 636
    minLineSize = 40
492
    
637

  
493 638
    ## Horizontal
494 639
    find = False
495 640
    startX = 0
496 641
    lineList = []
497 642
    for y in range(start, end):
498 643
        for x in range(0, img.shape[1]):
499
            if img[y,x] == 0:
644
            if img[y, x] == 0:
500 645
                if find:
501 646
                    continue
502 647
                else:
......
505 650
            else:
506 651
                if find:
507 652
                    if x - startX > minLineSize:
508
                        lineList.append(((startX,y), (x,y)))
653
                        lineList.append(((startX, y), (x, y)))
509 654

  
510 655
                    find = False
511 656
    _queue.put(lineList)
DTI_PID/DTI_PID/DetectSymbol_UI.py
2 2

  
3 3
# Form implementation generated from reading ui file '.\UI\DetectSymbol.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.13.0
5
# Created by: PyQt5 UI code generator 5.13.2
6 6
#
7 7
# WARNING! All changes made in this file will be lost!
8 8

  
......
22 22
        DetectSymbolDialog.setWindowIcon(icon)
23 23
        self.gridLayout = QtWidgets.QGridLayout(DetectSymbolDialog)
24 24
        self.gridLayout.setObjectName("gridLayout")
25
        self.horizontalLayout = QtWidgets.QHBoxLayout()
26
        self.horizontalLayout.setObjectName("horizontalLayout")
27
        self.pushButtonImportSymbolLibrary = QtWidgets.QPushButton(DetectSymbolDialog)
28
        self.pushButtonImportSymbolLibrary.setObjectName("pushButtonImportSymbolLibrary")
29
        self.horizontalLayout.addWidget(self.pushButtonImportSymbolLibrary)
30
        self.pushButtonExportSymbolLibrary = QtWidgets.QPushButton(DetectSymbolDialog)
31
        self.pushButtonExportSymbolLibrary.setObjectName("pushButtonExportSymbolLibrary")
32
        self.horizontalLayout.addWidget(self.pushButtonExportSymbolLibrary)
33
        self.buttonBox = QtWidgets.QDialogButtonBox(DetectSymbolDialog)
34
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
35
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
36
        self.buttonBox.setObjectName("buttonBox")
37
        self.horizontalLayout.addWidget(self.buttonBox)
38
        self.gridLayout.addLayout(self.horizontalLayout, 3, 0, 1, 1)
25 39
        self.gridLayout_2 = QtWidgets.QGridLayout()
26 40
        self.gridLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
27 41
        self.gridLayout_2.setObjectName("gridLayout_2")
......
33 47
        self.pushButtonDetectSymbol.setObjectName("pushButtonDetectSymbol")
34 48
        self.gridLayout_2.addWidget(self.pushButtonDetectSymbol, 0, 0, 1, 1)
35 49
        self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
36
        self.buttonBox = QtWidgets.QDialogButtonBox(DetectSymbolDialog)
37
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
38
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
39
        self.buttonBox.setObjectName("buttonBox")
40
        self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1)
41 50
        self.splitter_2 = QtWidgets.QSplitter(DetectSymbolDialog)
42 51
        self.splitter_2.setOrientation(QtCore.Qt.Horizontal)
43 52
        self.splitter_2.setObjectName("splitter_2")
......
99 108

  
100 109
    def retranslateUi(self, DetectSymbolDialog):
101 110
        _translate = QtCore.QCoreApplication.translate
102
        DetectSymbolDialog.setWindowTitle(_translate("DetectSymbolDialog", "심볼 관리자"))
111
        DetectSymbolDialog.setWindowTitle(_translate("DetectSymbolDialog", "Symbol Manager"))
112
        self.pushButtonImportSymbolLibrary.setText(_translate("DetectSymbolDialog", "Import Symbol Library"))
113
        self.pushButtonExportSymbolLibrary.setText(_translate("DetectSymbolDialog", "Export Symbol Library"))
103 114
        self.pushButtonDetectSymbol.setText(_translate("DetectSymbolDialog", "Detect Symbol"))
104 115
import MainWindow_rc
DTI_PID/DTI_PID/ID2.pro
5 5
SOURCES += ItemDataExport_UI.py ItemDataExportDialog.py HMB_UI.py RecognitionDialog.py LineNoTracer.py
6 6
SOURCES += ConnectAttr_UI.py ItemTreeWidget.py
7 7
SOURCES += CodeTable_UI.py CodeTableDialog.py
8
SOURCES += DetectSymbol_UI.py DetectSymbolDialog.py
8 9
SOURCES += .\UI\DataTransfer_UI.py DataTransferDialog.py
9 10
SOURCES += .\UI\DataExport_UI.py DataExportDialog.py
10 11
SOURCES += .\UI\EqpDatasheetExport_UI.py DataExportDialog.py
DTI_PID/DTI_PID/MainWindow.py
260 260
        self.actionSave.triggered.connect(self.actionSaveCliked)
261 261
        self.addMessage.connect(self.onAddMessage)
262 262
        self.actionFindReplaceText.triggered.connect(self.findReplaceTextClicked)
263
        self.pushButtonDetectSymbol.clicked.connect(self.onShowDetectSymbol)
263
        self.pushButtonDetectSymbol.clicked.connect(self.show_detect_symbol_dialog)
264 264
        #self.graphicsView.scene.contents_changed.connect(self.scene_changed)
265 265

  
266 266
        configs = docData.getAppConfigs('app', 'mode')
......
513 513
        drawing = os.path.join(appDocData.getCurrentProject().getDrawingFilePath(), item.text(0))
514 514
        self.onOpenImageDrawing(drawing)
515 515

  
516
    def onShowDetectSymbol(self):
516
    def show_detect_symbol_dialog(self):
517 517
        from DetectSymbolDialog import QDetectSymbolDialog
518 518

  
519
        dlgDetectSymbol = QDetectSymbolDialog(self)
520
        dlgDetectSymbol.show()
521
        dlgDetectSymbol.exec_()
519
        dlg = QDetectSymbolDialog(self)
520
        dlg.exec_()
522 521

  
523 522
    '''
524 523
        @brief      OCR Editor
DTI_PID/DTI_PID/QtImageViewer.py
1 1
# coding: utf-8
2 2
import sys
3 3
import os.path
4

  
4 5
try:
5 6
    from PyQt5.QtCore import *
6 7
    from PyQt5.QtGui import *
......
11 12
        from PyQt4.QtGui import *
12 13
    except ImportError:
13 14
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
14
    
15

  
15 16
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
16 17
import DefaultCommand
17 18

  
......
48 49
    rightMouseButtonReleased = pyqtSignal(float, float)
49 50
    leftMouseButtonDoubleClicked = pyqtSignal(float, float)
50 51
    rightMouseButtonDoubleClicked = pyqtSignal(float, float)
51
    #itemRemoved = pyqtSignal(QGraphicsItem)
52
    # itemRemoved = pyqtSignal(QGraphicsItem)
52 53
    startPointChanged = pyqtSignal(float, float)
53 54

  
54 55
    '''
55 56
        @history    2018.06.27  Jeongwoo    Change zoom rule (Qt.KeepAspectRatioByExpanding → Qt.KeepAspectRatio)
56 57
    '''
57
    def __init__(self, mainWindow = None):
58

  
59
    def __init__(self, mainWindow=None):
58 60
        from QtImageViewerScene import QtImageViewerScene
59 61

  
60 62
        QGraphicsView.__init__(self)
......
64 66
        self.command = None
65 67
        self.scene = QtImageViewerScene(self)
66 68
        self.setScene(self.scene)
67
        #self.scene.setBackgroundBrush(Qt.lightGray)
69
        # self.scene.setBackgroundBrush(Qt.lightGray)
68 70

  
69 71
        self.scaleFactor = 1.0
70 72
        self.numScheduledScalings = 0
......
99 101
        self.canPan = True
100 102
        self.setMouseTracking(True)
101 103
        self.command = None
102
        
104

  
103 105
        self.guidesEnabled = False
104 106
        self._guidePen = QPen()
105 107
        self._guidePen.setColor(QColor(180, 180, 180))
......
114 116
        @author     Jeongwoo
115 117
        @date       2018.06.11
116 118
    '''
119

  
117 120
    def getPixmapHandle(self):
118 121
        return self._pixmapHandle
119 122

  
......
123 126
        @date       18.04.10
124 127
        @history    .
125 128
    '''
129

  
126 130
    def useDefaultCommand(self):
127 131
        """ Use Default Command
128 132
        """
......
181 185
            self.setSceneRect(QRectF(pixmap.rect()))  # Set scene size to image size.
182 186
            self.updateViewer()
183 187
        except Exception as ex:
184
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
188
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
189
                                                       sys.exc_info()[-1].tb_lineno))
185 190

  
186 191
    '''
187 192
        @brief  open a image file selected by user
188 193
        @author 
189 194
        @date
190 195
    '''
196

  
191 197
    def loadImageFromFile(self, folder='', fileName=""):
192 198
        import cv2
193 199
        import numpy as np
......
201 207
                options = QFileDialog.Options()
202 208
                options |= QFileDialog.DontUseNativeDialog
203 209
                if QT_VERSION_STR[0] == '4':
204
                    fileName = QFileDialog.getOpenFileName(self, "Open image file", os.getcwd() if folder == '' else folder, "Image files(*.png *.jpg)", options=options)
210
                    fileName = QFileDialog.getOpenFileName(self, "Open image file",
211
                                                           os.getcwd() if folder == '' else folder,
212
                                                           "Image files(*.png *.jpg)", options=options)
205 213
                elif QT_VERSION_STR[0] == '5':
206
                    fileName, dummy = QFileDialog.getOpenFileName(self, "Open image file", os.getcwd() if folder == '' else folder, "Image files(*.png *.jpg)", options=options)
214
                    fileName, dummy = QFileDialog.getOpenFileName(self, "Open image file",
215
                                                                  os.getcwd() if folder == '' else folder,
216
                                                                  "Image files(*.png *.jpg)", options=options)
207 217
            if len(fileName) and os.path.isfile(fileName):
208 218
                cvImg = cv2.cvtColor(AppDocData.my_imread(fileName), cv2.COLOR_BGR2GRAY)
209
                #blur = cv2.GaussianBlur(cvImg, (5,5),0)
210
                cvImg = cv2.threshold(cvImg, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
219
                # blur = cv2.GaussianBlur(cvImg, (5,5),0)
220
                cvImg = cv2.threshold(cvImg, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
211 221

  
212 222
                # skeletonize
213 223
                '''
......
242 252
                        done = True
243 253
                cvImg = ~skel
244 254
                '''
245
                
255

  
246 256
                configs = AppDocData.instance().getConfigs('Filter', 'DilateSize')
247 257
                if 1 == len(configs) and int(configs[0].value) is not 0:
248 258
                    size = int(configs[0].value)
......
260 270
                image = QImage(cvImg.data, cvImg.shape[1], cvImg.shape[0], bytesPerLine, QImage.Format_Indexed8)
261 271
                self.setImage(image)
262 272
        except Exception as ex:
263
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
273
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
274
                                                       sys.exc_info()[-1].tb_lineno))
264 275

  
265 276
        return fileName
266 277

  
267 278
    '''
268 279
        @history    2018.06.27  Jeongwoo    Change zoom rule (Qt.KeepAspectRatioByExpanding → Qt.KeepAspectRatio)
269 280
    '''
281

  
270 282
    def updateViewer(self, zoomNewRect=None):
271 283
        """ Show current zoom (if showing entire image, apply current aspect ratio mode).
272 284
        """
273 285
        if not self.hasImage():
274 286
            return
275
        if len(self.zoomStack):# and self.sceneRect().contains(self.zoomStack[-1]):
287
        if len(self.zoomStack):  # and self.sceneRect().contains(self.zoomStack[-1]):
276 288
            if zoomNewRect is None:
277 289
                self.fitInView(self.zoomStack[-1], Qt.KeepAspectRatio)  # Show zoomed rect (ignore aspect ratio).
278 290
            else:
......
293 305
        @date       -
294 306
        @history    18.04.11    Jeongwoo    add parameter 'adjust' (@ref ResultTreeWidget.itemClickEvent(self, item, columnNo))
295 307
    '''
296
    def zoomImage(self, isZoomIn, event, adjust = 1):
308

  
309
    def zoomImage(self, isZoomIn, event, adjust=1):
297 310
        """ Zoom in & out
298 311
        """
299 312

  
300 313
        HALF_SIZE = 300
301 314
        clickPos = event.pos()
302
        scenePos1 = self.mapToScene(clickPos.x() - HALF_SIZE//adjust, clickPos.y() - HALF_SIZE//adjust)
303
        scenePos2 = self.mapToScene(clickPos.x() + HALF_SIZE//adjust, clickPos.y() + HALF_SIZE//adjust)
315
        scenePos1 = self.mapToScene(clickPos.x() - HALF_SIZE // adjust, clickPos.y() - HALF_SIZE // adjust)
316
        scenePos2 = self.mapToScene(clickPos.x() + HALF_SIZE // adjust, clickPos.y() + HALF_SIZE // adjust)
304 317
        if isZoomIn:
305
            zoomArea = QRectF(QPointF(scenePos1.x() if scenePos1.x() > 0 else 0, scenePos1.y() if scenePos1.y() > 0 else 0), QPointF(scenePos2.x(), scenePos2.y()))
306
            #self.fitInView(zoomArea, Qt.KeepAspectRatioByExpanding)
318
            zoomArea = QRectF(
319
                QPointF(scenePos1.x() if scenePos1.x() > 0 else 0, scenePos1.y() if scenePos1.y() > 0 else 0),
320
                QPointF(scenePos2.x(), scenePos2.y()))
321
            # self.fitInView(zoomArea, Qt.KeepAspectRatioByExpanding)
307 322
            viewBBox = self.zoomStack[-1] if len(self.zoomStack) else self.sceneRect()
308 323
            selectionBBox = zoomArea.intersected(viewBBox)
309 324
            self.scene.setSelectionArea(QPainterPath())  # Clear current selection area.
310
            if selectionBBox.width() > HALF_SIZE*2 and selectionBBox.height() > HALF_SIZE*2:
325
            if selectionBBox.width() > HALF_SIZE * 2 and selectionBBox.height() > HALF_SIZE * 2:
311 326
                if selectionBBox.isValid() and (selectionBBox != viewBBox):
312 327
                    self.zoomStack.append(selectionBBox)
313 328
                    self.updateViewer()
......
335 350
    '''
336 351
        @brief  mouse move event
337 352
    '''
353

  
338 354
    def mouseMoveEvent(self, event):
339 355
        try:
340 356
            scenePos = self.mapToScene(event.pos())
......
344 360
                    QGraphicsView.mouseMoveEvent(self, event)
345 361
                if self.command.isTreated == True: return
346 362
        except Exception as ex:
347
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
363
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
364
                                                       sys.exc_info()[-1].tb_lineno))
348 365

  
349 366
        if self.guidesEnabled:
350 367
            self.coords = self.mapToScene(event.pos())
......
358 375
        @date       
359 376
        @history    block clear selection when right mouse button is clicked
360 377
    '''
378

  
361 379
    def mousePressEvent(self, event):
362 380
        try:
363 381
            if self.command is not None:
......
365 383
                self.command.execute(['mousePressEvent', event, scenePos])
366 384
                if self.command.isTreated == True: return
367 385
        except Exception as ex:
368
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
386
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
387
                                                       sys.exc_info()[-1].tb_lineno))
369 388

  
370 389
        if event.button() != Qt.RightButton:
371 390
            QGraphicsView.mousePressEvent(self, event)
......
375 394
        @author     
376 395
        @date       
377 396
    '''
397

  
378 398
    def mouseReleaseEvent(self, event):
379 399
        try:
380 400
            if self.command is not None:
......
383 403
                if instance is not None:
384 404
                    self.scene.addItem(instance)
385 405

  
386
                if self.command is not None and self.command.isTreated == True: 
406
                if self.command is not None and self.command.isTreated == True:
387 407
                    if self.command.name == 'Default' and self.command.isCopy:
388 408
                        return
389 409
                    self.command = DefaultCommand.DefaultCommand(self)
......
391 411
                    QApplication.instance().setOverrideCursor(cursor)
392 412
                    return
393 413
        except Exception as ex:
394
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
414
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
415
                                                       sys.exc_info()[-1].tb_lineno))
395 416

  
396 417
        QGraphicsView.mouseReleaseEvent(self, event)
397
    
418

  
398 419
    """
399 420
        @brief      Show entire image.
400 421
    """
422

  
401 423
    def mouseDoubleClickEvent(self, event):
402 424
        scenePos = self.mapToScene(event.pos())
403 425
        if self.command is not None:
......
411 433
                self.zoomStack = []  # Clear zoom stack.
412 434
                self.updateViewer()
413 435
            self.rightMouseButtonDoubleClicked.emit(scenePos.x(), scenePos.y())
414
        
436

  
415 437
        QGraphicsView.mouseDoubleClickEvent(self, event)
416 438

  
417 439
    '''
......
420 442
        @date       2018.??.??
421 443
        @history    send escape key event to command
422 444
    '''
445

  
423 446
    def keyPressEvent(self, event):
424 447
        from TrainingEditorDialog import QTrainingEditorDialog
425 448
        from TrainingSymbolEditorDialog import QTrainingSymbolEditorDialog
......
440 463
                self.mainWindow.keyPressEvent(event)
441 464

  
442 465
            if event.key() == Qt.Key_Up or event.key() == Qt.Key_Down or event.key() == Qt.Key_Left or event.key() == Qt.Key_Right:
443
                items = [text for text in self.scene.selectedItems() if issubclass(type(text), QEngineeringTextItem)] #or issubclass(type(text), SymbolSvgItem)]
466
                items = [text for text in self.scene.selectedItems() if
467
                         issubclass(type(text), QEngineeringTextItem)]  # or issubclass(type(text), SymbolSvgItem)]
444 468
                if len(items) > 1:
445 469
                    for item in items:
446 470
                        item.keyPressEvent(event)
......
448 472

  
449 473
            QGraphicsView.keyPressEvent(self, event)
450 474
        except Exception as ex:
451
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
475
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
476
                                                       sys.exc_info()[-1].tb_lineno))
452 477

  
453 478
    '''
454 479
        @brief  key release event
455 480
        @author Jeongwoo
456 481
        @date   2018.??.??
457 482
    '''
483

  
458 484
    def keyReleaseEvent(self, event):
459 485
        if event.key() == Qt.Key_Delete:
460 486
            pass
......
466 492
        @autor      humkyung
467 493
        @date       
468 494
    '''
495

  
469 496
    def wheelEvent(self, event):
470 497
        if event.modifiers() == Qt.ControlModifier:
471 498
            if self.canZoom and self.hasImage():
......
481 508
    '''
482 509
        @brief      
483 510
    '''
511

  
484 512
    def drawForeground(self, painter, rect):
485 513
        if hasattr(self, 'coords') and self.guidesEnabled:
486 514
            painter.setClipRect(rect)
......
510 538
        @brief      draw background
511 539
        @author     humkyung
512 540
        @date       2018.07.23
513
    '''        
541
    '''
542

  
514 543
    def drawBackground(self, painter, rect):
515
        QGraphicsView.drawBackground(self, painter, rect) 
544
        QGraphicsView.drawBackground(self, painter, rect)
516 545

  
517 546
    '''
518 547
        @history    2018.06.11  Jeongwoo    Change method to manage guideline items
519 548
                    humkyung 2018.08.28 remove guide lines before drawing
520 549
    '''
521 550
    GUIDELINE_ITEMS = []
551

  
522 552
    def showGuideline(self, pos, isShow):
523 553
        image = self.image()
524 554
        width = image.width()
......
538 568
                verticalLine = self.scene.addLine(pos.x(), 0, pos.x(), height, pen)
539 569
                horizontalLine = self.scene.addLine(0, pos.y(), width, pos.y(), pen)
540 570
            else:
541
                verticalLine = self.scene.addLine(round(width*0.5), 0, round(width*0.5), height, pen)
542
                horizontalLine = self.scene.addLine(0, round(height*0.5), width, round(height*0.5), pen)
571
                verticalLine = self.scene.addLine(round(width * 0.5), 0, round(width * 0.5), height, pen)
572
                horizontalLine = self.scene.addLine(0, round(height * 0.5), width, round(height * 0.5), pen)
543 573

  
544 574
            self.GUIDELINE_ITEMS.append(verticalLine)
545 575
            self.GUIDELINE_ITEMS.append(horizontalLine)
......
555 585
        @author humkyung
556 586
        @date   2018.04.17
557 587
    '''
588

  
558 589
    def dragEnterEvent(self, event):
559 590
        event.acceptProposedAction()
560 591

  
......
564 595
        @date       2018.04.17
565 596
        @history    humkyung 2018.08.21 highlight item under mouse
566 597
    '''
598

  
567 599
    def dragMoveEvent(self, event):
568 600
        scenePos = self.mapToScene(event.pos())
569
        items = [item for item in self.scene.items(scenePos) if type(item) is not QGraphicsPixmapItem and type(item) is not QGraphicsTextItem]
601
        items = [item for item in self.scene.items(scenePos) if
602
                 type(item) is not QGraphicsPixmapItem and type(item) is not QGraphicsTextItem]
570 603
        if len(items) > 0:
571 604
            if not hasattr(self, '_underItem') or self._underItem is not items[0]:
572 605
                if hasattr(self, '_underItem') and self._underItem is not None:
......
578 611
                self._underItem = items[0]
579 612
                if hasattr(self._underItem, 'highlight'):
580 613
                    self._underItem.highlight(True)
581
        #elif hasattr(self, '_underItem') and self._underItem is not None:
614
        # elif hasattr(self, '_underItem') and self._underItem is not None:
582 615
        #    self._underItem.hoverLeaveEvent(event)
583 616
        #    self._underItem = None
584
        
617

  
585 618
        event.acceptProposedAction()
586 619

  
587 620
    '''
......
591 624
        @history    2018.06.08  Jeongwoo    Add Paramter on SymbolSvgItem.buildItem()
592 625
                    humkyung 2018.08.21 call hoverLeaveEvent if item exists under mouse
593 626
    '''
627

  
594 628
    def dropEvent(self, event):
595 629
        from AppDocData import AppDocData
596 630
        import symbol
597
        
631

  
598 632
        if len(self.scene.items()) is 0:
599 633
            return
600 634
        if hasattr(self, '_underItem') and self._underItem is not None and self._underItem in self.scene.items():
......
604 638
            self._underItem = None
605 639

  
606 640
        scenePos = self.mapToScene(event.pos())
607
        svgFileName = event.mimeData().text()
608
        svg = self.createSymbolObject(svgFileName)
641
        name = event.mimeData().text()
642
        svg = self.createSymbolObject(name)
609 643
        self.matchSymbolToLine(svg, scenePos)
610 644

  
611
        #if type(svg) is QEngineeringSpecBreakItem:
612
        #   self.command.specBreak_startPoint = [scenePos.x(), scenePos.y()]
613
        #    self.command.isCopy = True
614
        #    self.command.isSpecBreak = True
615
        #    self.command.symbol = svg
616
        #    while 0 != svg.angle:
617
        #        svg.rotateSymbol()
618

  
619 645
        event.acceptProposedAction()
620 646

  
621 647
    '''
......
623 649
        @author kyouho
624 650
        @date   2018.07.27
625 651
    '''
626
    def createSymbolObject(self, svgFileName):
652

  
653
    def createSymbolObject(self, name):
654
        """create a symbol object has given uid"""
627 655
        from AppDocData import AppDocData
628
        import symbol
629
        
630
        symbol = AppDocData.instance().getSymbolByQuery('name', svgFileName)
631
        svgFilePath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), symbol.getType(), svgFileName+'.svg')
656

  
657
        app_doc_data = AppDocData.instance()
658

  
659
        symbol = app_doc_data.getSymbolByQuery('Name', name)
660
        svg_file_name = symbol.sName
661
        svgFilePath = os.path.join(app_doc_data.getCurrentProject().getSvgFilePath(), symbol.getType(),
662
                                   svg_file_name + '.svg')
632 663
        svg = SymbolSvgItem.createItem(symbol.getType(), svgFilePath)
633 664
        connPts = None
634 665
        strConnPts = symbol.getConnectionPoint()
635 666
        if strConnPts is not None and strConnPts != '':
636
            connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) if len(x.split(',')) == 2 else (x.split(',')[0], float(x.split(',')[1]), float(x.split(',')[2])) \
637
            for x in strConnPts.split('/')]
667
            connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) if len(x.split(',')) == 2 else (
668
            x.split(',')[0], float(x.split(',')[1]), float(x.split(',')[2])) \
669
                       for x in strConnPts.split('/')]
670

  
671
        svg.buildItem(svg_file_name, symbol.getType(), 0, None, None, None, connPts, symbol.getBaseSymbol(),
672
                      symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel())
638 673

  
639
        svg.buildItem(svgFileName, symbol.getType(), 0, None, None, None, connPts, symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel())
640
        
641 674
        return svg
642
        
675

  
643 676
    '''
644 677
        @brief      match symbol to line
645 678
        @author     kyouho
646 679
        @date       2018.07.27
647 680
        @history    humkyung 2018.08.23 change scenePos to connector's center when symbol is placed on connector
648 681
    '''
682

  
649 683
    def matchSymbolToLine(self, svg, scenePos):
650 684
        from EngineeringConnectorItem import QEngineeringConnectorItem
651 685
        from EngineeringLineItem import QEngineeringLineItem
......
654 688

  
655 689
        svg.transfer.onRemoved.connect(self.mainWindow.itemRemoved)
656 690

  
657
        items = [item for item in self.scene.items(scenePos) if type(item) is not QGraphicsPixmapItem and type(item) is not QGraphicsTextItem]
691
        items = [item for item in self.scene.items(scenePos) if
692
                 type(item) is not QGraphicsPixmapItem and type(item) is not QGraphicsTextItem]
658 693
        connectors = []
659 694
        if len(items) > 0 and type(items[0]) is QEngineeringConnectorItem:
660 695
            scenePos = QPointF(items[0].center()[0], items[0].center()[1])
661 696
            connectors = [connector for connector in items if issubclass(type(connector.parentItem()), SymbolSvgItem)]
662 697

  
663
        matches = [item for item in self.scene.items() if (type(item) is QEngineeringLineItem) and (item.distanceTo((scenePos.x(), scenePos.y())) < 20)]
698
        matches = [item for item in self.scene.items() if
699
                   (type(item) is QEngineeringLineItem) and (item.distanceTo((scenePos.x(), scenePos.y())) < 20)]
664 700
        allowed_error = 0.00001
665
        if False:#len(matches) == 1:
701
        if False:  # len(matches) == 1:
666 702
            matches[0].insertSymbol(svg, scenePos)
667 703
        elif len(connectors) == 1 and len(svg.connectors) >= 2 and len(connectors[0].parentItem().connectors):
668 704
            # item assistant with line connection
......
671 707
            length = math.sqrt(xl * xl + yl * yl)
672 708
            ddx = (connectors[0].sceneBoundingRect().center().x() - connectors[0].parentItem().origin[0]) / length
673 709
            ddy = (connectors[0].sceneBoundingRect().center().y() - connectors[0].parentItem().origin[1]) / length
674
            dx, dy = abs(svg.connectors[0].connectPoint[0] - svg.symbolOrigin[0]), abs(svg.connectors[0].connectPoint[1] - svg.symbolOrigin[1])
710
            dx, dy = abs(svg.connectors[0].connectPoint[0] - svg.symbolOrigin[0]), abs(
711
                svg.connectors[0].connectPoint[1] - svg.symbolOrigin[1])
675 712
            length = math.sqrt(dx * dx + dy * dy)
676 713
            dx, dy = length * ddx, length * ddy
677
        
678
            #if abs(connectors[0].parentItem().angle - math.pi / 2) < allowed_error or abs(connectors[0].parentItem().angle - math.pi / 2 * 3) < allowed_error:
714

  
715
            # if abs(connectors[0].parentItem().angle - math.pi / 2) < allowed_error or abs(connectors[0].parentItem().angle - math.pi / 2 * 3) < allowed_error:
679 716
            #    dx, dy = ddx * dy, ddy * dx
680
            #else:
717
            # else:
681 718
            #    dx, dy = ddx * dx, ddy * dy
682
                
719

  
683 720
            flip = connectors[0].parentItem().flip
684 721
            angle = connectors[0].parentItem().angle
685 722

  
686 723
            rAngle = math.atan2(yl, xl) if flip == 0 else math.atan2(yl, -xl)
687 724
            rAngle = abs(rAngle) if rAngle < 0 + allowed_error else 2 * math.pi - rAngle
688 725
            svg.angle = angle + rAngle if angle + rAngle < 2 * math.pi else angle + rAngle - 2 * math.pi
689
            
726

  
690 727
            '''
691 728
            if connectors[0].parentItem().connectors.index(connectors[0]) == 0:
692 729
                if flip == 0:
......
717 754
                    svg.angle = angle
718 755
            '''
719 756

  
720
            x, y = connectors[0].sceneBoundingRect().center().x() + dx, connectors[0].sceneBoundingRect().center().y() + dy
757
            x, y = connectors[0].sceneBoundingRect().center().x() + dx, connectors[
758
                0].sceneBoundingRect().center().y() + dy
721 759
            svg.loc = [x - svg.symbolOrigin[0], y - svg.symbolOrigin[1]]
722 760
            svg.origin = [x, y]
723 761
            svg.addSvgItemToScene(self.scene)
724 762

  
725
            items = [item for item in self.scene.items(scenePos) if type(item) is not QGraphicsPixmapItem and type(item) is not QGraphicsTextItem]
763
            items = [item for item in self.scene.items(scenePos) if
764
                     type(item) is not QGraphicsPixmapItem and type(item) is not QGraphicsTextItem]
726 765
            items = [item for item in items if item.parentItem() is svg]
727 766
            if items and connectors[0].connectedItem and type(connectors[0].connectedItem) is QEngineeringLineItem:
728 767
                items[0].connectedItem = connectors[0].parentItem()
......
752 791
            svg.origin = [round(scenePos.x(), 1), round(scenePos.y(), 1)]
753 792
            if len(svg.connectors) == 1:
754 793
                # single connection item assistant
755
                items = [item for item in self.scene.items(scenePos) if type(item) is QEngineeringConnectorItem and item.parentItem() is not svg and issubclass(type(item.parentItem()), SymbolSvgItem) and not item.connectedItem]
794
                items = [item for item in self.scene.items(scenePos) if
795
                         type(item) is QEngineeringConnectorItem and item.parentItem() is not svg and issubclass(
796
                             type(item.parentItem()), SymbolSvgItem) and not item.connectedItem]
756 797
                if items:
757 798
                    '''
758 799
                    xl = connectors[0].parentItem().symbolOrigin[0] - connectors[0].connectPoint[0]
......
773 814

  
774 815
            svg.addSvgItemToScene(self.scene)
775 816

  
776
        #svg.reSettingConnetors()
817
        # svg.reSettingConnetors()
777 818

  
778 819
        self.scene.clearFocus()
779 820
        for item in self.scene.selectedItems():
......
788 829
        @author kyouho
789 830
        @date   2018.07.31
790 831
    '''
832

  
791 833
    def findItemByUid(self, uid):
792 834
        from EngineeringConnectorItem import QEngineeringConnectorItem
793 835

  
794 836
        items = [item for item in self.scene.items() if hasattr(item, 'uid') and str(item.uid) == str(uid)]
795 837
        return items[0] if items else None
796 838

  
839

  
797 840
if __name__ == '__main__':
798 841
    import sys
842

  
799 843
    try:
800 844
        from PyQt5.QtWidgets import QApplication
801 845
    except ImportError:
......
805 849
            raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
806 850
    print('Using Qt ' + QT_VERSION_STR)
807 851

  
852

  
808 853
    def handleLeftClick(x, y):
809 854
        row = int(y)
810 855
        column = int(x)
811
        print("Clicked on image pixel (row="+str(row)+", column="+str(column)+")")
856
        print("Clicked on image pixel (row=" + str(row) + ", column=" + str(column) + ")")
857

  
812 858

  
813 859
    # Create the application.
814 860
    app = QApplication(sys.argv)
DTI_PID/DTI_PID/Shapes/SymbolSvgItem.py
75 75
        self.conn_type = []
76 76

  
77 77
        try:
78
            f = QFile(path)
79
            f.open(QIODevice.ReadOnly)
80
            array = f.readAll()
78
            app_doc_data = AppDocData.instance()
79
            svg = None
80
            if path and os.path.isfile(path):
81
                f = QFile(path)
82
                f.open(QIODevice.ReadOnly)
83
                svg = f.readAll()
84
                f.close()
85

  
81 86
            self._document = QDomDocument()
82
            self._document.setContent(array)
87
            self._document.setContent(svg)
83 88
            self._renderer = QSvgRenderer(self._document.toByteArray())
84 89
            self.setSharedRenderer(self._renderer)
85 90

  
......
87 92
        except Exception as ex:
88 93
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
89 94
                                                      sys.exc_info()[-1].tb_lineno))
90
        finally:
91
            f.close()
92 95

  
93 96
        self.setZValue(SymbolSvgItem.ZVALUE)
94 97

  
DTI_PID/DTI_PID/SymbolAttrEditorDialog.py
191 191
            row = row + 1
192 192

  
193 193
    def saveData(self):
194
        """
195
        @brief      save data
196
        @author     humkyung
197
        @date       2018.08.14
198
        @history    humkyung 2018.10.13 save expression
199
        """
194
        """save symbol attributes"""
200 195

  
201 196
        appDocData = AppDocData.instance()
202 197

  
......
273 268
        QDialog.accept(self)
274 269

  
275 270
    '''
276
        @brief      remove attribute at secne
277
        @author     kyoyho
278
        @date       2018.08.20
279
    '''
280
    def reSettingSceneAttribute(self):
281
        from App import App
282
        App.mainWnd().checkAttribute()
283

  
284
    '''
285 271
        @brief  setting attribute table line no
286 272
        @author kyoyho
287 273
        @date   2018.08.21
DTI_PID/DTI_PID/SymbolEditorDialog.py
14 14
import cv2
15 15

  
16 16
import SymbolEditor_UI
17
from AppDocData import * 
17
from AppDocData import *
18 18
from LineTypeConditions import LineTypeConditions
19 19

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

  
23 24

  
24 25
class QSymbolEditorDialog(QDialog):
......
32 33
                                            Remove self.dbHelper variable
33 34
                    2018.07.03  Yecheol     Rename File, Is Instrument Label added
34 35
    '''
35
    def __init__(self, parent, image, project, selectedSymbol = None, display = False):
36

  
37
    def __init__(self, parent, image, project, selectedSymbol=None, display=False):
36 38
        QDialog.__init__(self, parent)
37 39

  
38 40
        try:
......
45 47
            self.ui = SymbolEditor_UI.Ui_Dialog()
46 48
            self.ui.setupUi(self)
47 49
            self.ui.tableWidgetConnList.setColumnCount(6)
48
            self.ui.tableWidgetConnList.setHorizontalHeaderLabels([self.tr('Position'), self.tr('Direction'), self.tr('Symbol'), self.tr('In_out'), self.tr('Break'), self.tr('Type')])
50
            self.ui.tableWidgetConnList.setHorizontalHeaderLabels(
51
                [self.tr('Position'), self.tr('Direction'), self.tr('Symbol'), self.tr('In_out'), self.tr('Break'),
52
                 self.tr('Type')])
49 53
            self.ui.tableWidgetConnList.horizontalHeaderItem(0).setSizeHint(QSize(25, 25))
50 54
            self.ui.tableWidgetConnList.itemPressed.connect(self.onConnPtPressed)
51 55

  
......
58 62
            self.isAccepted = False
59 63
            self.offsetX = 0
60 64
            self.offsetY = 0
61
            self.newSym = None            
65
            self.newSym = None
62 66

  
63 67
            # for display image
64 68
            if display:
......
93 97
            self.ui.hasInstrumentLabelCheckBox.setHidden(True)
94 98
            self.ui.immediateInsertLabel.setHidden(True)
95 99
            self.ui.immediateInsertCheckBox.setHidden(True)
96
            
100

  
97 101
            self.ui.label_3.setHidden(True)
98 102
            self.ui.label_4.setHidden(True)
99 103
            self.ui.checkBoxChange.setHidden(True)
......
101 105
        except Exception as ex:
102 106
            from App import App
103 107

  
104
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
108
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
109
                                                           sys.exc_info()[-1].tb_lineno)
105 110
            App.mainWnd().addMessage.emit(MessageType.Error, message)
106 111

  
107 112
    def changeSymbolInfo(self):
......
116 121
        mainScene = App.mainWnd().graphicsView
117 122
        if not mainScene.hasImage():
118 123
            return
119
        symbols = [item for item in mainScene.items() if issubclass(type(item), SymbolSvgItem) and item.name == self.selectedSymbol.getName()]
124
        symbols = [item for item in mainScene.items() if
125
                   issubclass(type(item), SymbolSvgItem) and item.name == self.selectedSymbol.getName()]
120 126
        newBase = self.ui.baseSymbolComboBox.currentText()
121 127
        newAddition = self.makeAdditionalSymbolListString()
122 128
        newType = self.ui.typeComboBox.currentText()
......
130 136
        @author     humkyung
131 137
        @date       2018.08.31
132 138
    '''
139

  
133 140
    def onConnPtPressed(self, item):
134 141
        data = item.data(Qt.UserRole)
135 142
        if data is not None:
......
150 157

  
151 158
            ptr = incomingImage.bits()
152 159
            ptr.setsize(incomingImage.byteCount())
153
            arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
160
            arr = np.array(ptr).reshape(height, width, 4)  # Copies the data
154 161
            return arr
155 162
        except Exception as ex:
156 163
            from App import App
157 164

  
158
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
165
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
166
                                                           sys.exc_info()[-1].tb_lineno)
159 167
            App.mainWnd().addMessage.emit(MessageType.Error, message)
160 168

  
161 169
    '''
162 170
        @brief  Set up QtImageViewer and QImage
163 171
        @history    2018.05.02  Jeongwoo    Connect imageviewer and QSymbolEditorDialog
164 172
    '''
173

  
165 174
    def setupImageViewer(self):
166 175
        from MainWindow import MainWindow
167 176

  
......
190 199
        @history    2018.05.03  Jeongwoo    Add connection for removeTextButton
191 200
                    2018.06.11  Jeongwoo    Add connection for rotation and flip
192 201
    '''
... 이 차이점은 표시할 수 있는 최대 줄수를 초과해서 이 차이점은 잘렸습니다.

내보내기 Unified diff

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