개정판 cf1f887b
fixed issue #578:
- 심볼이 소팅되어 표시
- NOZZLE이 해당 EQUIPMENT 하위에 표시
- DELETE KEY를 눌러 심볼 삭제
DTI_PID/DTI_PID/DTI_PID.py | ||
---|---|---|
606 | 606 |
if overlapArea <= ACCEPT_OVERLAY_AREA: |
607 | 607 |
threadLock.acquire() |
608 | 608 |
foundSymbolCount = foundSymbolCount + 1 |
609 |
addSearchedSymbol(symbolName, symbolType |
|
609 |
searched = addSearchedSymbol(symbolName, symbolType
|
|
610 | 610 |
, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolAngle |
611 | 611 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
612 | 612 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect) |
613 |
searched.owner = equipment |
|
613 | 614 |
threadLock.release() |
614 | 615 |
## 겹치는 영역이 기준값보다 클 경우 |
615 | 616 |
else: |
... | ... | |
629 | 630 |
elif appDocData.isEquipmentType(searchedSymbol.getType()): |
630 | 631 |
threadLock.acquire() |
631 | 632 |
foundSymbolCount = foundSymbolCount + 1 |
632 |
addSearchedSymbol(symbolName, symbolType |
|
633 |
searched = addSearchedSymbol(symbolName, symbolType
|
|
633 | 634 |
, searchedItemSp, sw, sh, symbolThreshold, hitRate, hitRate, symbolAngle |
634 | 635 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
635 | 636 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect) |
637 |
searched.owner = equipment |
|
636 | 638 |
threadLock.release() |
637 | 639 |
|
638 | 640 |
## Rotate Symbol |
... | ... | |
1074 | 1076 |
|
1075 | 1077 |
appDocData.imgName = os.path.splitext(os.path.basename(mainRes))[0] |
1076 | 1078 | |
1077 |
print('removing detected symbols') |
|
1078 | 1079 |
pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER) |
1079 | 1080 |
for sym in searchedSymbolList: |
1080 | 1081 |
pool.submit(removeDetectedSymbol, sym, appDocData.imgSrc) |
1081 | 1082 |
#pool.submit(drawRectOnSrc, sym) |
1082 | 1083 |
pool.shutdown(wait = True) |
1083 |
print('removed detected symbols') |
|
1084 | ||
1084 | 1085 |
''' |
1085 | 1086 |
global MIN_TEXT_SIZE |
1086 | 1087 |
for textInfo in textInfoList: |
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
662 | 662 |
try: |
663 | 663 |
project = AppDocData.instance().getCurrentProject() |
664 | 664 | |
665 |
searchedMap = [] |
|
665 | 666 |
for symbol in symbolList: |
666 | 667 |
pt = [float(x) for x in symbol.getSp()] |
667 | 668 |
size = [symbol.getWidth(), symbol.getHeight()] |
... | ... | |
684 | 685 |
svg = SymbolSvgItem.createItem(type, svgFilePath) |
685 | 686 |
svg.buildItem(name, type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel) |
686 | 687 | |
687 |
#### lambda param=svg : bind 'svg' object to lambda('param') |
|
688 |
#### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda |
|
689 |
#svg.clicked.connect(lambda param=svg: self.svgItemClicked(param)) |
|
688 |
# set owner - 2018.07.20 added by humkyung |
|
689 |
matches = [searched for searched in searchedMap if searched[0] == symbol.owner] |
|
690 |
if len(matches) == 1: |
|
691 |
svg.owner = matches[0][1] |
|
692 |
searchedMap.append((symbol, svg)) |
|
693 |
# up to here |
|
694 | ||
690 | 695 |
svg.removed.connect(self.itemRemoved) |
691 | 696 |
self.addSvgItemToScene(svg) |
692 | 697 |
for connector in svg.connectors: |
... | ... | |
695 | 700 |
item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1]) |
696 | 701 |
item.isSymbol = True |
697 | 702 |
item.angle = angle |
698 |
item.setPen(QPen(Qt.red, 10, Qt.SolidLine))
|
|
703 |
item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
|
|
699 | 704 |
self.graphicsView.scene.addItem(item) |
700 | 705 |
# up to here |
701 | 706 |
except Exception as ex: |
... | ... | |
840 | 845 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse |
841 | 846 | |
842 | 847 |
try: |
843 |
project = AppDocData.instance().getCurrentProject()
|
|
848 |
symbols = []
|
|
844 | 849 | |
845 | 850 |
xml = parse(xmlPath) |
846 | 851 |
root = xml.getroot() |
847 | 852 |
for symbol in root.iter('SYMBOL'): |
848 |
pt = [float(x) for x in symbol.find('LOCATION').text.split(',')] |
|
849 |
size = [float(x) for x in symbol.find('SIZE').text.split(',')] |
|
850 |
name = symbol.find('NAME').text |
|
851 |
angle = float(symbol.find('ANGLE').text) |
|
852 |
type = symbol.find('TYPE').text |
|
853 |
origin = [float(x) for x in symbol.find('ORIGINALPOINT').text.split(',')] |
|
854 |
connPts = [] |
|
855 |
if symbol.find('CONNECTIONPOINT').text is not None: |
|
856 |
connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) for x in symbol.find('CONNECTIONPOINT').text.split('/')] |
|
857 |
baseSymbol = symbol.find('PARENT').text |
|
858 |
childSymbolNode = symbol.find('CHILD') |
|
859 |
childSymbol = '' |
|
860 |
if childSymbolNode is not None: |
|
861 |
childSymbol = childSymbolNode.text |
|
862 |
|
|
863 |
hasInstrumentLabelNode = symbol.find('HASINSTRUMENTLABEL') |
|
864 |
hasInstrumentLabel = hasInstrumentLabelNode.text if hasInstrumentLabelNode is not None else 'False' |
|
865 | ||
866 |
svgFilePath = os.path.join(project.getSvgFilePath(), type, name + '.svg') |
|
867 |
if os.path.isfile(svgFilePath): |
|
868 |
svg = SymbolSvgItem.createItem(type, svgFilePath) |
|
869 |
svg.buildItem(name, type, angle, pt, size, origin, connPts, baseSymbol, childSymbol, hasInstrumentLabel) |
|
870 | ||
871 |
svg.removed.connect(self.itemRemoved) |
|
872 |
self.addSvgItemToScene(svg) |
|
873 |
for connector in svg.connectors: |
|
874 |
self.graphicsView.scene.addItem(connector) |
|
853 |
item = SymbolSvgItem.fromXml(symbol) |
|
854 |
if item[0] is not None: |
|
855 |
item[0].removed.connect(self.itemRemoved) |
|
856 |
symbols.append(item) |
|
875 | 857 |
else: |
858 |
pt = [float(x) for x in symbol.find('LOCATION').text.split(',')] |
|
859 |
size = [float(x) for x in symbol.find('SIZE').text.split(',')] |
|
860 |
angle = float(symbol.find('ANGLE').text) |
|
876 | 861 |
item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1]) |
877 | 862 |
item.isSymbol = True |
878 | 863 |
item.angle = angle |
879 |
item.setPen(QPen(Qt.red, 10, Qt.SolidLine))
|
|
864 |
item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
|
|
880 | 865 |
self.graphicsView.scene.addItem(item) |
881 | 866 | |
867 |
# set symbol's owner |
|
868 |
childItems = [item for item in symbols if item[1] is not None] |
|
869 |
for item in childItems: |
|
870 |
matches = [param for param in symbols if str(param[0].uid) == item[1]] |
|
871 |
if len(matches) == 1: |
|
872 |
item[0].owner = matches[0][0] |
|
873 |
# up to here |
|
874 |
|
|
875 |
for item in symbols: |
|
876 |
self.addSvgItemToScene(item[0]) |
|
877 |
for connector in item[0].connectors: |
|
878 |
self.graphicsView.scene.addItem(connector) |
|
879 | ||
882 | 880 |
docData = AppDocData.instance() |
883 | 881 |
configs = docData.getConfigs('Line No', 'Delimiter') |
884 | 882 |
delimiter = configs[0].value if 1 == len(configs) else '-' |
DTI_PID/DTI_PID/QDirTreeWidget.py | ||
---|---|---|
86 | 86 |
Use project object when making svgPath |
87 | 87 |
''' |
88 | 88 |
def handleDeleteSymbolAction(self, result, itemType, itemName): |
89 |
print("handle") |
|
90 | 89 |
if result == QMessageBox.Ok: |
91 | 90 |
project = AppDocData.instance().getCurrentProject() |
92 |
imagePath = project.getImageFilePath() + "/" + itemType + "/" + itemName + ".png" # itemName DOESN'T includes ".png"
|
|
91 |
imagePath = os.path.join(project.getImageFilePath(), itemType, itemName + '.png') # itemName DOESN'T includes ".png"
|
|
93 | 92 |
if os.path.exists(imagePath): |
94 | 93 |
os.remove(imagePath) |
95 | 94 | |
96 |
svgPath = project.getSvgFilePath() + "/" + itemType + "/" + itemName + ".svg"
|
|
95 |
svgPath = os.path.join(project.getSvgFilePath(), itemType, itemName + '.svg')
|
|
97 | 96 |
if os.path.exists(svgPath): |
98 | 97 |
os.remove(svgPath) |
99 | 98 | |
... | ... | |
113 | 112 |
projectPath = project.getPath().replace("\\", "/") |
114 | 113 |
self.makeChildDir() |
115 | 114 |
self.loadSymbolInfo() |
116 |
#self.loadDirectoryInfo(project.getImageFilePath(), self) |
|
117 | 115 |
self.expandAll() |
118 | 116 | |
119 | 117 |
''' |
DTI_PID/DTI_PID/ResultPropertyTableWidget.py | ||
---|---|---|
177 | 177 |
''' |
178 | 178 |
def initTitleCell(self, item): |
179 | 179 |
try: |
180 |
if issubclass(type(item), SymbolSvgItem) or type(item) is SymbolSvgItem:
|
|
181 |
self.setRowCount(4)
|
|
180 |
if issubclass(type(item), SymbolSvgItem): |
|
181 |
self.setRowCount(5)
|
|
182 | 182 | |
183 | 183 |
self.setItem(0, 0, QTableWidgetItem("심볼명")) |
184 | 184 |
self.setItem(1, 0, QTableWidgetItem("타입")) |
185 | 185 |
self.setItem(2, 0, QTableWidgetItem("각도")) |
186 | 186 |
self.setItem(3, 0, QTableWidgetItem("원점")) |
187 |
self.setItem(4, 0, QTableWidgetItem("OWNER")) |
|
187 | 188 |
elif type(item) is QEngineeringNoteItem: |
188 | 189 |
self.setRowCount(1) |
189 | 190 | |
... | ... | |
226 | 227 |
from QEngineeringInstrumentItem import QEngineeringInstrumentItem |
227 | 228 | |
228 | 229 |
if self.symData is not None: |
229 |
self.setRowCount(self.rowCount() + len(self.symData.getAttributes()) + len(self.symData.conns)) |
|
230 | ||
231 | 230 |
self.setItem(0, 1, QTableWidgetItem(self.symData.name)) |
232 | 231 |
self.setItem(1, 1, QTableWidgetItem(self.symData.type)) |
233 | 232 |
self.setItem(2, 1, QTableWidgetItem(str(round(math.degrees(self.symData.angle))))) |
234 | 233 |
self.setItem(3, 1, QTableWidgetItem(str(self.symData.origin))) |
234 |
self.setItem(4, 1, QTableWidgetItem('{}'.format(self.symData.owner))) |
|
235 | 235 | |
236 |
row = 4 |
|
236 |
row = self.rowCount() |
|
237 |
self.setRowCount(row + len(self.symData.getAttributes()) + len(self.symData.conns)) |
|
237 | 238 |
# display attributes of symbol |
238 | 239 |
attrs = self.symData.getAttributes() |
239 | 240 |
if attrs is not None: |
... | ... | |
241 | 242 |
for index in range(len(attrItems)): |
242 | 243 |
key = attrItems[index][0] |
243 | 244 |
value = attrItems[index][1] |
244 |
keyItem = QTableWidgetItem(key)
|
|
245 |
keyItem.setBackground(QColor(220, 220, 220))
|
|
246 |
self.setItem(3 + index, 0, keyItem)
|
|
247 |
self.setItem(3 + index, 1, QTableWidgetItem(value))
|
|
245 |
item = QTableWidgetItem(key)
|
|
246 |
item.setBackground(QColor(220, 220, 220))
|
|
247 |
self.setItem(row + index, 0, item)
|
|
248 |
self.setItem(row + index, 1, QTableWidgetItem(value))
|
|
248 | 249 |
row = row + 1 |
249 | 250 |
# up to here |
250 | 251 | |
251 | 252 |
# display connectivity |
252 | 253 |
count = 1 |
253 |
self.setRowCount(row + len(self.symData.conns)) |
|
254 | 254 |
for conn in self.symData.conns: |
255 | 255 |
item = QTableWidgetItem('CONN{}'.format(count)) |
256 | 256 |
item.setFlags(Qt.ItemIsEnabled) |
DTI_PID/DTI_PID/ResultTreeWidget.py | ||
---|---|---|
1 | 1 |
# coding: utf-8 |
2 | 2 | |
3 |
import os |
|
4 |
import re |
|
5 |
import sys |
|
6 | ||
3 | 7 |
try: |
4 | 8 |
from PyQt5.QtCore import * |
5 | 9 |
from PyQt5.QtGui import * |
... | ... | |
18 | 22 |
from QEngineeringUnknownItem import QEngineeringUnknownItem |
19 | 23 |
from AppDocData import AppDocData |
20 | 24 |
from Drawing import Drawing |
21 |
import os |
|
22 |
import re |
|
23 | 25 | |
24 | 26 |
class QResultTreeWidget(QTreeWidget): |
25 |
TREE_DATA_ROLE = Qt.ToolTipRole
|
|
27 |
TREE_DATA_ROLE = Qt.UserRole
|
|
26 | 28 | |
27 | 29 |
#Add Signal |
28 | 30 |
singleClicked = pyqtSignal(SymbolSvgItem) |
... | ... | |
41 | 43 |
self.root = None |
42 | 44 |
self.setContextMenuPolicy(Qt.CustomContextMenu) |
43 | 45 |
self.customContextMenuRequested.connect(self.openContextMenu) |
44 |
|
|
46 | ||
47 |
''' |
|
48 |
@brief delete selected symbol |
|
49 |
@author humkyung |
|
50 |
@date 2018.07.20 |
|
51 |
''' |
|
52 |
def keyPressEvent(self, event): |
|
53 |
try: |
|
54 |
if event.key() == Qt.Key_Delete: |
|
55 |
if self.selectedItems(): |
|
56 |
for item in self.selectedItems(): |
|
57 |
data = item.data(0, self.TREE_DATA_ROLE) |
|
58 |
if data is not None: |
|
59 |
self.imageViewer.scene.removeItem(data) |
|
60 |
item.parent().removeChild(item) |
|
61 |
event.accept() |
|
62 |
else: |
|
63 |
event.ignore() |
|
64 |
except Exception as ex: |
|
65 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
66 | ||
45 | 67 |
''' |
46 | 68 |
@brief Show Context Menu |
47 | 69 |
@author Jeongwoo |
... | ... | |
171 | 193 |
Jeongwoo 2018.05.15 Add break keyword on if-statement |
172 | 194 |
Jeongwoo 2018.05.17 Set TreeWidgetItem's color with data's color And Set Data's color on LineNoTextItem Setting |
173 | 195 |
humkyung 2018.06.12 add unknown item |
196 |
humkyung 2018.07.20 append nozzle to equipment |
|
174 | 197 |
''' |
175 | 198 |
def addTreeItem(self, parent, child): |
176 | 199 |
item = None |
... | ... | |
180 | 203 |
symbolsRootItem = self.findItems('EQUIPMENTS', Qt.MatchExactly|Qt.MatchRecursive, 0) |
181 | 204 |
symbolsRootItem = symbolsRootItem[0] |
182 | 205 |
item = QTreeWidgetItem(symbolsRootItem, [child.name]) |
206 |
item.setData(0, self.TREE_DATA_ROLE, child) |
|
207 |
elif child.type == 'Nozzles': |
|
208 |
eqpRootTreeItem = self.findItems('EQUIPMENTS', Qt.MatchExactly|Qt.MatchRecursive, 0) |
|
209 |
for i in range(eqpRootTreeItem[0].childCount()): |
|
210 |
eqpTreeItem = eqpRootTreeItem[0].child(i) |
|
211 |
eqpSymbol = eqpTreeItem.data(0, self.TREE_DATA_ROLE) |
|
212 |
if child.owner is eqpSymbol: |
|
213 |
symbolsRootItem = eqpTreeItem |
|
214 |
item = QTreeWidgetItem(eqpTreeItem, [child.name]) |
|
215 |
item.setData(0, self.TREE_DATA_ROLE, child) |
|
216 |
break |
|
217 |
|
|
218 |
if item is None: |
|
219 |
symbolsRootItem = self.findItems('SYMBOLS', Qt.MatchExactly|Qt.MatchRecursive, 0) |
|
220 |
symbolsRootItem = symbolsRootItem[0] |
|
221 |
item = QTreeWidgetItem(symbolsRootItem, [child.name]) |
|
183 | 222 |
else: |
184 | 223 |
symbolsRootItem = self.findItems('SYMBOLS', Qt.MatchExactly|Qt.MatchRecursive, 0) |
185 | 224 |
symbolsRootItem = symbolsRootItem[0] |
186 | 225 |
item = QTreeWidgetItem(symbolsRootItem, [child.name]) |
187 |
iconPath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), child.type , child.name + ".svg") |
|
188 |
item.setIcon(0, QIcon(iconPath)) |
|
189 |
item.setData(0, self.TREE_DATA_ROLE, child) |
|
190 |
brush = QBrush() |
|
191 |
brush.setColor(QColor(child.getColor())) |
|
192 |
item.setForeground(0, brush) |
|
193 |
item.setFont(0, item.font(0)) |
|
194 |
child.treeItem = item |
|
195 |
symbolsRootItem.addChild(item) |
|
226 |
|
|
227 |
if item is not None: |
|
228 |
iconPath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), child.type , child.name + ".svg") |
|
229 |
item.setIcon(0, QIcon(iconPath)) |
|
230 |
item.setData(0, self.TREE_DATA_ROLE, child) |
|
231 |
brush = QBrush() |
|
232 |
brush.setColor(QColor(child.getColor())) |
|
233 |
item.setForeground(0, brush) |
|
234 |
item.setFont(0, item.font(0)) |
|
235 |
child.treeItem = item |
|
236 |
symbolsRootItem.addChild(item) |
|
237 |
symbolsRootItem.sortChildren(0, Qt.AscendingOrder) # sort childrens |
|
196 | 238 |
elif type(child) is QEngineeringLineNoTextItem: |
197 | 239 |
item = QTreeWidgetItem([child.text()]) |
198 | 240 |
item.setFlags(item.flags() | Qt.ItemIsUserCheckable) |
... | ... | |
269 | 311 |
@date 18.04.11 |
270 | 312 |
@history Jeongwoo 2018.04.25 Add QEngineeringNoteItem to list for loop / NOT QEngineeringTextItem |
271 | 313 |
Jeongwoo 2018.04.26 Change changedSceneItems conditions in loop (QEngineeringTextItem → QEngineeringLineNoTextItem) |
314 |
humkyung 2018.07.20 put items which's owner is None before item which's owner is not None |
|
272 | 315 |
''' |
273 | 316 |
lastSceneItems = None |
274 | 317 |
def sceneChanged(self, sceneItems): |
275 | 318 |
changedSceneItems = [item for item in sceneItems if ((issubclass(type(item), SymbolSvgItem)) or (type(item) is QEngineeringNoteItem) or (type(item) is QEngineeringLineNoTextItem) |
276 | 319 |
or (type(item) is QEngineeringUnknownItem)) and (not hasattr(item, 'treeItem') or item.treeItem is None)] # Sublist includes SymbolSvgItem |
277 |
self.initResultTreeWidget(changedSceneItems) |
|
320 |
first = [item for item in changedSceneItems if item.owner is None] |
|
321 |
second = [item for item in changedSceneItems if item.owner is not None] |
|
322 |
self.initResultTreeWidget(first + second) |
|
278 | 323 |
|
279 | 324 |
''' |
280 | 325 |
@brief Initialize TreeWidget |
... | ... | |
324 | 369 | |
325 | 370 |
itemData = item.data(0, self.TREE_DATA_ROLE) |
326 | 371 |
|
327 |
#if self.lastClickedItem is not None: |
|
328 |
# self.scene.removeItem(self.lastClickedItem) |
|
329 | ||
330 | 372 |
if itemData is not None: ## Not PID Name |
331 | 373 |
if issubclass(type(itemData), SymbolSvgItem): |
332 | 374 |
## Draw rectangle on selected symbol |
... | ... | |
354 | 396 |
self.imageViewer.centerOn(rect.center()) |
355 | 397 |
## Send new event to imageViewer's zoomImage Method |
356 | 398 |
self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3) |
357 |
#self.lastClickedItem = graphicItem |
|
358 |
#noteContentsList = self.findNoteContents(itemData.text()) |
|
359 | 399 |
noteContentsList = itemData.findNoteContents(itemData.text()) |
360 | 400 | |
361 | 401 |
self.noteNoSingleClicked.emit(itemData.text(), noteContentsList) |
DTI_PID/DTI_PID/Shapes/QEngineeringEquipmentItem.py | ||
---|---|---|
17 | 17 | |
18 | 18 |
''' |
19 | 19 |
''' |
20 |
def __init__(self, path): |
|
21 |
import uuid |
|
22 | ||
23 |
SymbolSvgItem.__init__(self, path) |
|
20 |
def __init__(self, path, uid=None): |
|
21 |
SymbolSvgItem.__init__(self, path, uid) |
|
24 | 22 | |
25 | 23 |
''' |
26 | 24 |
@brief connect attribute |
DTI_PID/DTI_PID/Shapes/QEngineeringInstrumentItem.py | ||
---|---|---|
17 | 17 | |
18 | 18 |
''' |
19 | 19 |
''' |
20 |
def __init__(self, path): |
|
21 |
import uuid |
|
22 | ||
23 |
SymbolSvgItem.__init__(self, path) |
|
20 |
def __init__(self, path, uid=None): |
|
21 |
SymbolSvgItem.__init__(self, path, uid) |
|
24 | 22 | |
25 | 23 |
self._measuredVairableCode = None |
26 | 24 |
self._typeModifier = None |
DTI_PID/DTI_PID/Shapes/QEngineeringNozzleItem.py | ||
---|---|---|
17 | 17 | |
18 | 18 |
''' |
19 | 19 |
''' |
20 |
def __init__(self, path): |
|
21 |
import uuid |
|
22 | ||
23 |
SymbolSvgItem.__init__(self, path) |
|
20 |
def __init__(self, path, uid=None): |
|
21 |
SymbolSvgItem.__init__(self, path, uid) |
|
24 | 22 | |
25 | 23 |
''' |
26 | 24 |
@brief connect attribute |
DTI_PID/DTI_PID/Shapes/QEngineeringOPCItem.py | ||
---|---|---|
17 | 17 | |
18 | 18 |
''' |
19 | 19 |
''' |
20 |
def __init__(self, path): |
|
21 |
import uuid |
|
22 | ||
23 |
SymbolSvgItem.__init__(self, path) |
|
20 |
def __init__(self, path, uid=None): |
|
21 |
SymbolSvgItem.__init__(self, path, uid) |
|
24 | 22 | |
25 | 23 |
''' |
26 | 24 |
@brief getter of description |
DTI_PID/DTI_PID/Shapes/SymbolSvgItem.py | ||
---|---|---|
26 | 26 |
18.05.25 Jeongwoo Call setColor() method |
27 | 27 |
18.05.30 Jeongwoo Add self variables (parentSymbol, childSymbol) |
28 | 28 |
''' |
29 |
def __init__(self, path): |
|
29 |
def __init__(self, path, uid=None):
|
|
30 | 30 |
import uuid |
31 | 31 | |
32 | 32 |
QGraphicsSvgItem.__init__(self) |
... | ... | |
35 | 35 |
self.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable) |
36 | 36 |
#QGraphicsItem.ItemIsMovable) |
37 | 37 |
|
38 |
self.uid = uuid.uuid4() # generate UUID
|
|
38 |
self.uid = uuid.uuid4() if uid is None else uid
|
|
39 | 39 |
self.name = '' |
40 | 40 |
self.type = '' |
41 | 41 |
self.angle = 0 |
... | ... | |
71 | 71 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
72 | 72 |
finally: |
73 | 73 |
f.close() |
74 |
|
|
74 | 75 |
''' |
75 | 76 |
@breif getter owner |
76 | 77 |
@author humkyung |
... | ... | |
513 | 514 |
humkyung 2018.05.02 add attribute of symbol |
514 | 515 |
Jeongwoo 2018.05.30 add attribute of symbol (parentSymbol, childSymbol, type, connectionPoint) |
515 | 516 |
yecheol 2018.07.11 add attribute of symbol (hasInstrumentLabel) |
517 |
humkyung 2018.07.20 write owner's uid to xml |
|
516 | 518 |
''' |
517 | 519 |
def toXml(self): |
518 | 520 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
... | ... | |
531 | 533 |
typeNode.text = self.type |
532 | 534 |
node.append(typeNode) |
533 | 535 | |
536 |
# write owner's uid to xml |
|
537 |
if self.owner is not None: |
|
538 |
ownerNode = Element('OWNER') |
|
539 |
ownerNode.text = str(self.owner.uid) |
|
540 |
node.append(ownerNode) |
|
541 |
# up to here |
|
542 | ||
534 | 543 |
originNode = Element('ORIGINALPOINT') |
535 | 544 |
originNode.text = '{},{}'.format(self.origin[0], self.origin[1]) |
536 | 545 |
node.append(originNode) |
... | ... | |
585 | 594 |
parent.append(attr.toXml(self)) |
586 | 595 | |
587 | 596 |
''' |
597 |
@brief parse xml code |
|
598 |
@author humkyung |
|
599 |
@date 2018.07.20 |
|
600 |
@history humkyung 2018.07.20 parse uid from xml node |
|
601 |
''' |
|
602 |
@staticmethod |
|
603 |
def fromXml(node): |
|
604 |
import uuid |
|
605 |
item = [None, None] |
|
606 | ||
607 |
try: |
|
608 |
uidNode = node.find('UID') |
|
609 |
uid = uuid.UUID(uidNode.text) if uidNode is not None else uuid.uuid4() # generate UUID |
|
610 | ||
611 |
pt = [float(x) for x in node.find('LOCATION').text.split(',')] |
|
612 |
size = [float(x) for x in node.find('SIZE').text.split(',')] |
|
613 |
name = node.find('NAME').text |
|
614 |
angle = float(node.find('ANGLE').text) |
|
615 |
type = node.find('TYPE').text |
|
616 |
origin = [float(x) for x in node.find('ORIGINALPOINT').text.split(',')] |
|
617 |
connPts = [] |
|
618 |
if node.find('CONNECTIONPOINT').text is not None: |
|
619 |
connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) for x in node.find('CONNECTIONPOINT').text.split('/')] |
|
620 |
baseSymbol = node.find('PARENT').text |
|
621 |
childSymbolNode = node.find('CHILD') |
|
622 |
childSymbol = '' |
|
623 |
if childSymbolNode is not None: |
|
624 |
childSymbol = childSymbolNode.text |
|
625 |
|
|
626 |
ownerNode = node.find('OWNER') |
|
627 |
owner = ownerNode.text if ownerNode is not None else None |
|
628 | ||
629 |
hasInstrumentLabelNode = node.find('HASINSTRUMENTLABEL') |
|
630 |
hasInstrumentLabel = hasInstrumentLabelNode.text if hasInstrumentLabelNode is not None else 'False' |
|
631 | ||
632 |
project = AppDocData.instance().getCurrentProject() |
|
633 |
svgFilePath = os.path.join(project.getSvgFilePath(), type, name + '.svg') |
|
634 |
if os.path.isfile(svgFilePath): |
|
635 |
item[0] = SymbolSvgItem.createItem(type, svgFilePath, uid) |
|
636 |
item[0].buildItem(name, type, angle, pt, size, origin, connPts, baseSymbol, childSymbol, hasInstrumentLabel) |
|
637 |
item[1] = owner |
|
638 |
except Exception as ex: |
|
639 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
640 | ||
641 |
return item |
|
642 | ||
643 |
''' |
|
588 | 644 |
@brief create item corresponding to given type |
589 | 645 |
@author humkyung |
590 | 646 |
@date 2018.05.02 |
... | ... | |
593 | 649 |
humkyung 2018.07.19 create nozzle instance if type is 'Nozzles' |
594 | 650 |
''' |
595 | 651 |
@staticmethod |
596 |
def createItem(type, path): |
|
652 |
def createItem(type, path, uid=None):
|
|
597 | 653 |
from QEngineeringOPCItem import QEngineeringOPCItem |
598 | 654 |
from QEngineeringEquipmentItem import QEngineeringEquipmentItem |
599 | 655 |
from QEngineeringInstrumentItem import QEngineeringInstrumentItem |
... | ... | |
605 | 661 |
item = None |
606 | 662 |
cateogry = docData.getSymbolCategoryByType(type) |
607 | 663 |
if type == "Piping OPC's": |
608 |
item = QEngineeringOPCItem(path) |
|
664 |
item = QEngineeringOPCItem(path, uid)
|
|
609 | 665 |
elif cateogry == 'Equipment': |
610 |
item = QEngineeringEquipmentItem(path) |
|
666 |
item = QEngineeringEquipmentItem(path, uid)
|
|
611 | 667 |
elif cateogry == 'Instrumentation': |
612 |
item = QEngineeringInstrumentItem(path) |
|
668 |
item = QEngineeringInstrumentItem(path, uid)
|
|
613 | 669 |
elif type == 'Nozzles': |
614 |
item = QEngineeringNozzleItem(path)
|
|
670 |
item = QEngineeringNozzleItem(path, uid)
|
|
615 | 671 |
else: |
616 |
item = SymbolSvgItem(path) |
|
672 |
item = SymbolSvgItem(path, uid)
|
|
617 | 673 | |
618 | 674 |
return item |
619 | 675 |
DTI_PID/DTI_PID/SymbolBase.py | ||
---|---|---|
7 | 7 |
, isDetectOnOrigin = False, rotationCount = 4, ocrOption = OCR_OPTION_NOT_EXEC, isContainChild = 0 |
8 | 8 |
, originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None |
9 | 9 |
, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None): |
10 |
#def __init__(self, id, sName, sType, path = None, threshold = None, minMatchCount = 0 |
|
11 |
# , isDetectOnOrigin = False, rotationCount = 4, ocrOption = OCR_OPTION_NOT_EXEC, isContainChild = 0 |
|
12 |
# , originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None |
|
13 |
# , uid = None): |
|
14 | 10 |
self.uid = uid ## Auto increased Unique Id |
15 |
#self.id = id ## Symbol Id |
|
16 | 11 |
self.sName = sName |
17 | 12 |
self.sType = sType |
18 |
#self.path = path |
|
19 | 13 |
self.threshold = threshold |
20 | 14 |
self.minMatchCount = minMatchCount |
21 | 15 |
self.isDetectOnOrigin = isDetectOnOrigin |
... | ... | |
28 | 22 |
self.additionalSymbol = additionalSymbol |
29 | 23 |
self.isExceptDetect = isExceptDetect |
30 | 24 |
self.hasInstrumentLabel = hasInstrumentLabel |
31 |
|
|
25 |
self._owner = None |
|
32 | 26 | |
33 | 27 |
def setUid(self, uid): |
34 | 28 |
self.uid = uid |
... | ... | |
36 | 30 |
def getUid(self): |
37 | 31 |
return self.uid |
38 | 32 | |
39 |
''' |
|
40 |
def setId(self, id): |
|
41 |
self.id = id |
|
42 |
''' |
|
43 |
''' |
|
44 |
def getId(self): |
|
45 |
return self.id |
|
46 |
''' |
|
47 | ||
48 | 33 |
def setName(self, sName): |
49 | 34 |
self.sName = sName |
50 | 35 | |
... | ... | |
57 | 42 |
def getType(self): |
58 | 43 |
return self.sType |
59 | 44 |
|
60 |
#def setPath(self, path): |
|
61 |
# self.path = path |
|
45 |
''' |
|
46 |
@brief getter of owner |
|
47 |
@author humkyung |
|
48 |
@date 2018.07.20 |
|
49 |
''' |
|
50 |
@property |
|
51 |
def owner(self): |
|
52 |
return self._owner |
|
62 | 53 | |
54 |
''' |
|
55 |
@brief setter of owner |
|
56 |
@author humkyung |
|
57 |
@date 2018.07.20 |
|
58 |
''' |
|
59 |
@owner.setter |
|
60 |
def owner(self, value): |
|
61 |
self._owner = value |
|
62 |
|
|
63 | 63 |
def getPath(self): |
64 | 64 |
from AppDocData import AppDocData |
65 |
#return self.path |
|
66 | 65 |
return AppDocData.instance().getCurrentProject().getImageFilePath() + "/" + self.sType + "/" + self.sName + ".png" |
67 | 66 | |
68 | 67 |
def setThreshold(self, threshold): |
... | ... | |
142 | 141 |
def getHasInstrumentLabel(self): |
143 | 142 |
return self.hasInstrumentLabel |
144 | 143 | |
145 | ||
146 | ||
147 | 144 |
''' |
148 | 145 |
@brief Get Image File Full Path |
149 | 146 |
@author Jeongwoo |
DTI_PID/DTI_PID/symbol.py | ||
---|---|---|
11 | 11 |
SymbolBase.__init__(self, sName, sType, threshold, minMatchCount |
12 | 12 |
, isDetectOnOrigin, rotationCount, ocrOption, isContainChild |
13 | 13 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid) |
14 |
#def __init__(self, id, sName, sType, path, sp, width, height, threshold, minMatchCount, mpCount, rotatedAngle |
|
15 |
# , isDetectOnOrigin, rotationCount, ocrOption, isContainChild = 0 |
|
16 |
# , originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None, uid = None): |
|
17 |
# SymbolBase.__init__(self, id, sName, sType, path, threshold, minMatchCount |
|
18 |
# , isDetectOnOrigin, rotationCount, ocrOption, isContainChild |
|
19 |
# , originalPoint, connectionPoint, baseSymbol, additionalSymbol, uid) |
|
20 | 14 |
self.sp = sp |
21 | 15 |
self.width = width |
22 | 16 |
self.height = height |
내보내기 Unified diff