개정판 b1a510c6
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