hytos / HYTOS / HYTOS / Shapes / SymbolSvgItem.py @ 03940dd1
이력 | 보기 | 이력해설 | 다운로드 (101 KB)
1 |
#!/usr/bin/env/python3
|
---|---|
2 |
# coding: utf-8
|
3 |
|
4 |
import sys |
5 |
import os |
6 |
import math |
7 |
from PyQt5.QtGui import * |
8 |
from PyQt5.QtCore import * |
9 |
from PyQt5.QtSvg import * |
10 |
from PyQt5.QtWidgets import (QApplication, QGraphicsItem) |
11 |
from PyQt5.QtXml import * |
12 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QMessageBox |
13 |
|
14 |
from AppDocData import * |
15 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
16 |
from EngineeringConnectorItem import QEngineeringConnectorItem |
17 |
from EngineeringEqpDescTextItem import QEngineeringEqpDescTextItem |
18 |
|
19 |
|
20 |
def is_float(s): |
21 |
try:
|
22 |
if s:
|
23 |
float(s)
|
24 |
return True |
25 |
else:
|
26 |
return False |
27 |
except ValueError: |
28 |
return False |
29 |
|
30 |
|
31 |
def is_blank(s): |
32 |
return not (s and s.strip()) |
33 |
|
34 |
|
35 |
def convert_to_fixed_point(value): |
36 |
if is_float(str(value)): |
37 |
tokens = f"{float(value):.10f}".split('.') |
38 |
if len(tokens) == 2: |
39 |
# 소수점 아래가 있을 경우 소수점 아래의 trailing zero를 제거한다.
|
40 |
if is_blank(tokens[1].rstrip('0')): |
41 |
return tokens[0] |
42 |
else:
|
43 |
tokens[1] = tokens[1].rstrip('0') |
44 |
return '.'.join(tokens) |
45 |
else:
|
46 |
return tokens[0] |
47 |
else:
|
48 |
return value
|
49 |
|
50 |
|
51 |
class SymbolSvgItem(QGraphicsSvgItem, QEngineeringAbstractItem): |
52 |
"""This is SymbolSvgItem class"""
|
53 |
|
54 |
clicked = pyqtSignal(QGraphicsSvgItem) |
55 |
ZVALUE = 100
|
56 |
HOVER_COLOR = 'url(#hover)'
|
57 |
COUNTERS = {} |
58 |
|
59 |
'''
|
60 |
@history 18.04.11 Jeongwoo Add Variable (Name, Type)
|
61 |
18.05.11 Jeongwoo Declare variable self.color
|
62 |
18.05.25 Jeongwoo Call setColor() method
|
63 |
18.05.30 Jeongwoo Add self variables (parentSymbol, childSymbol)
|
64 |
'''
|
65 |
|
66 |
def __init__(self, uid=None, flip=0, symbol=None): |
67 |
import uuid |
68 |
from SymbolAttr import SymbolProp |
69 |
|
70 |
QGraphicsSvgItem.__init__(self)
|
71 |
QEngineeringAbstractItem.__init__(self)
|
72 |
|
73 |
self.setFlags(
|
74 |
QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemIsMovable | |
75 |
QGraphicsItem.ItemSendsGeometryChanges | QGraphicsItem.ItemClipsToShape) |
76 |
|
77 |
self.dbUid = None |
78 |
self.uid = uuid.uuid4() if uid is None else uuid.UUID(uid, version=4) |
79 |
self.name = '' |
80 |
self.category = '' |
81 |
self.type = '' |
82 |
self.angle = 0 |
83 |
self._scales = [1, 1] |
84 |
self.origin = None |
85 |
self.loc = None |
86 |
self.size = None |
87 |
self._owner = None |
88 |
self.parentSymbol = '' |
89 |
self.childSymbol = '' |
90 |
self.hasInstrumentLabel = 0 |
91 |
# attributeType uid
|
92 |
self.attribute = {}
|
93 |
self._tag_no = None |
94 |
self._selected_idx = None |
95 |
self.setAcceptDrops(True) |
96 |
self.setAcceptHoverEvents(True) |
97 |
self.setAcceptedMouseButtons(Qt.LeftButton)
|
98 |
self.setAcceptTouchEvents(True) |
99 |
|
100 |
self.currentCursor = 0 |
101 |
self.transfer = Transfer()
|
102 |
|
103 |
try:
|
104 |
app_doc_data = AppDocData.instance() |
105 |
shape = None
|
106 |
if symbol:
|
107 |
shape = app_doc_data.read_symbol_shape(app_doc_data.activeDrawing.path, symbol) |
108 |
|
109 |
self._document = QDomDocument()
|
110 |
self._document.setContent(shape)
|
111 |
self._renderer = QSvgRenderer(self._document.toByteArray()) |
112 |
self.setSharedRenderer(self._renderer) |
113 |
|
114 |
self._color = self.get_attribute('fill') |
115 |
except Exception as ex: |
116 |
from App import App |
117 |
from AppDocData import MessageType |
118 |
|
119 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
120 |
sys.exc_info()[-1].tb_lineno)
|
121 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
122 |
|
123 |
self.setZValue(SymbolSvgItem.ZVALUE)
|
124 |
self.desc_labels = {}
|
125 |
|
126 |
def has_attribute(self): |
127 |
if len(self.attribute) > 0: |
128 |
return True |
129 |
else:
|
130 |
return False |
131 |
|
132 |
def __str__(self): |
133 |
""" return string represent uuid """
|
134 |
return str(self.uid) |
135 |
|
136 |
@property
|
137 |
def tag_no(self): |
138 |
return self._tag_no |
139 |
|
140 |
@tag_no.setter
|
141 |
def tag_no(self, value): |
142 |
self._tag_no = value
|
143 |
|
144 |
@property
|
145 |
def owner(self): |
146 |
"""getter owner"""
|
147 |
import uuid |
148 |
|
149 |
if self._owner and type(self._owner) is uuid.UUID: |
150 |
matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(self._owner)] |
151 |
if matches: self._owner = matches[0] |
152 |
|
153 |
if type(self._owner) is not uuid.UUID and type(self._owner) is not str: |
154 |
return self._owner |
155 |
else:
|
156 |
self._owner = None |
157 |
return None |
158 |
|
159 |
@owner.setter
|
160 |
def owner(self, value): |
161 |
"""setter owner"""
|
162 |
self._owner = value
|
163 |
|
164 |
if self._owner is None: |
165 |
self._color = self.DEFAULT_COLOR |
166 |
self.setColor(self._color) |
167 |
|
168 |
def validate(self): |
169 |
"""validate symbol data"""
|
170 |
|
171 |
res = [] |
172 |
|
173 |
for conn in self.connectors: |
174 |
error = conn.validate() |
175 |
if error:
|
176 |
res.append(error) |
177 |
|
178 |
return res
|
179 |
|
180 |
@property
|
181 |
def corners(self): |
182 |
rect = self.sceneBoundingRect()
|
183 |
return [rect.topLeft(), rect.bottomLeft(), rect.bottomRight(), rect.topRight()]
|
184 |
|
185 |
def resize(self, change): |
186 |
""" resize item """
|
187 |
try:
|
188 |
rect = self.boundingRect()
|
189 |
if rect.isValid():
|
190 |
scale = max(min([change.width() / rect.width(), change.height() / rect.height()]), 1) |
191 |
# scale the item
|
192 |
self.setScale(scale)
|
193 |
|
194 |
# scale down for label
|
195 |
for conn, label in self.desc_labels.items(): |
196 |
label.setScale(1/scale)
|
197 |
# up to here
|
198 |
|
199 |
self.prepareGeometryChange()
|
200 |
self.update()
|
201 |
except Exception as ex: |
202 |
from App import App |
203 |
|
204 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
205 |
sys.exc_info()[-1].tb_lineno)
|
206 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
207 |
|
208 |
def toSql(self): |
209 |
import uuid |
210 |
""" convert valve data to sql query """
|
211 |
|
212 |
res = [] |
213 |
|
214 |
try:
|
215 |
rect = self.sceneBoundingRect()
|
216 |
origin = self.mapToScene(self.transformOriginPoint()) |
217 |
trans = self.transform()
|
218 |
|
219 |
cols = ['UID', 'Symbols_UID', 'Name', '[Index]', 'X', 'Y', 'Rotation', 'ScaleX', 'ScaleY'] |
220 |
values = ['?', '?', '?', '?', '?', '?', '?', '?', '?'] |
221 |
param = [str(self.uid), str(self.dbUid), str(self.tag_no) if self.tag_no is not None else self.tag_no, |
222 |
self.index, origin.x(), origin.y(),
|
223 |
self.rotation(), trans.m11(), trans.m22()]
|
224 |
sql = 'insert or replace into Components({}) values({})'.format(','.join(cols), ','.join(values)) |
225 |
res.append((sql, tuple(param)))
|
226 |
|
227 |
# save connectors to database
|
228 |
index = 1
|
229 |
for connector in self.connectors: |
230 |
res.extend(connector.toSql(index)) |
231 |
index += 1
|
232 |
# up to here
|
233 |
|
234 |
# save nozzle label
|
235 |
for conn, label in self.desc_labels.items(): |
236 |
res.extend(label.toSql(conn)) |
237 |
# up to here
|
238 |
|
239 |
except Exception as ex: |
240 |
from App import App |
241 |
|
242 |
message = f'error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:' \
|
243 |
f'{sys.exc_info()[-1].tb_lineno}'
|
244 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
245 |
|
246 |
return res
|
247 |
|
248 |
def buildItem(self, name, _type, angle, scales: list, loc, origin, connPts, dbUid=None, pointsUids=None, index=None): |
249 |
"""build symbol item"""
|
250 |
|
251 |
from App import App |
252 |
|
253 |
try:
|
254 |
# index가 없을때(사용자 생성시) 같은 이름의 심볼 인덱스의 최대값 + 1을 index로 설정
|
255 |
if not index: |
256 |
matches = [item for item in App.mainWnd().graphicsView.scene.items() |
257 |
if type(item) is SymbolSvgItem and item.name == name] |
258 |
if matches:
|
259 |
matches.sort(key=lambda item: item.index)
|
260 |
index = matches[-1].index + 1 |
261 |
else:
|
262 |
index = 1
|
263 |
|
264 |
self.name = name
|
265 |
self.index = index
|
266 |
self.type = _type
|
267 |
self.angle = angle
|
268 |
self._scales = scales
|
269 |
self.loc = loc
|
270 |
|
271 |
app_doc_data = AppDocData.instance() |
272 |
if dbUid is None: |
273 |
symbolInfo = app_doc_data.getSymbolByQuery('name', name)
|
274 |
else:
|
275 |
symbolInfo = app_doc_data.getSymbolByQuery('UID', dbUid)
|
276 |
|
277 |
self.dbUid = symbolInfo.uid
|
278 |
self.category = symbolInfo.sCategory
|
279 |
originalPoint = symbolInfo.getOriginalPoint().split(',')
|
280 |
self.symbolOrigin = [float(originalPoint[0]), float(originalPoint[1])] |
281 |
|
282 |
# setting connectors
|
283 |
connectionPoints = symbolInfo.getConnectionPoint().split('/')
|
284 |
for index in range(len(connectionPoints)): |
285 |
if connectionPoints[index] == '': |
286 |
break
|
287 |
tokens = connectionPoints[index].split(',')
|
288 |
|
289 |
direction = 'AUTO'
|
290 |
symbol_idx = '0'
|
291 |
|
292 |
if len(tokens) == 2: |
293 |
x = float(tokens[0]) |
294 |
y = float(tokens[1]) |
295 |
elif len(tokens) == 3: |
296 |
direction = tokens[0]
|
297 |
x = float(tokens[1]) |
298 |
y = float(tokens[2]) |
299 |
elif len(tokens) == 4: |
300 |
direction = tokens[0]
|
301 |
x = float(tokens[1]) |
302 |
y = float(tokens[2]) |
303 |
symbol_idx = tokens[3]
|
304 |
|
305 |
if pointsUids:
|
306 |
self.set_connector(pointsUids[index], index + 1) |
307 |
else:
|
308 |
self.set_connector(None, index + 1) |
309 |
|
310 |
self.connectors[index].direction = direction
|
311 |
self.connectors[index].symbol_idx = symbol_idx
|
312 |
self.connectors[index].setPos((x, y))
|
313 |
self.connectors[index].connectPoint = (x, y)
|
314 |
|
315 |
tooltip = f"<b>{self.uid}</b><br>{self.type}={self.name}_{self.index}"
|
316 |
self.setToolTip(tooltip)
|
317 |
except Exception as ex: |
318 |
from App import App |
319 |
|
320 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
321 |
sys.exc_info()[-1].tb_lineno)
|
322 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
323 |
|
324 |
def get_label_pos_of_connector(self, conn, label): |
325 |
"""return label position of given connector"""
|
326 |
|
327 |
res = None
|
328 |
|
329 |
app_doc_data = AppDocData.instance() |
330 |
if conn.data.pos:
|
331 |
res = QPointF(conn.data.pos[0], conn.data.pos[1]) |
332 |
else:
|
333 |
label_rect = label.boundingRect() |
334 |
conn_rect = conn.mapRectFromParent(conn.boundingRect()) |
335 |
dx, dy = conn.dir() |
336 |
|
337 |
if dx == 1: |
338 |
res = QPointF(conn_rect.x() + conn_rect.width() * 0.5, conn_rect.y())
|
339 |
elif dy == -1: |
340 |
res = QPointF(conn_rect.x() + conn_rect.width()*0.5, conn_rect.y() - label_rect.height())
|
341 |
elif dy == 1: |
342 |
res = QPointF(conn_rect.x() + conn_rect.width()*0.5, conn_rect.y() + conn_rect.height()*0.5) |
343 |
elif dx == -1: |
344 |
res = QPointF(conn_rect.x() - label_rect.width(), conn_rect.y() + conn_rect.height()*0.5)
|
345 |
|
346 |
return res
|
347 |
|
348 |
def build_label(self): |
349 |
try:
|
350 |
"""build equipment label"""
|
351 |
|
352 |
rect = self.boundingRect()
|
353 |
|
354 |
app_doc_data = AppDocData.instance() |
355 |
units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0] |
356 |
|
357 |
self.update_label_contents()
|
358 |
|
359 |
if self.category == 'Equipment - [ Pressure Drop ]': |
360 |
if self.type == 'Air Fin Cooler': |
361 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
362 |
if conns:
|
363 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
364 |
self.desc_labels[conns[0]].setPos(pos) |
365 |
elif self.type == 'Filter': |
366 |
if self.tag_no: |
367 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
368 |
if conns:
|
369 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
370 |
self.desc_labels[conns[0]].setPos(pos) |
371 |
elif self.type == 'Heat Exchanger': |
372 |
if self.tag_no: |
373 |
nozzles = [] |
374 |
for conn in self.connectors: |
375 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
376 |
nozzle = str(conn).rsplit('_', 1)[1] |
377 |
nozzles.append(nozzle) |
378 |
|
379 |
if len(nozzles) > 0: |
380 |
if self.name == 'HEX_DP': |
381 |
if 'N1' in nozzles and 'N2' in nozzles: |
382 |
label_rect = self.desc_labels[self.connectors[0]].boundingRect() |
383 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
384 |
self.desc_labels[self.connectors[0]]) |
385 |
self.desc_labels[self.connectors[0]].setPos(pos) |
386 |
elif 'N1' in nozzles: |
387 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
388 |
self.desc_labels[self.connectors[0]]) |
389 |
self.desc_labels[self.connectors[0]].setPos(pos) |
390 |
elif 'N2' in nozzles: |
391 |
pos = self.get_label_pos_of_connector(self.connectors[1], |
392 |
self.desc_labels[self.connectors[1]]) |
393 |
self.desc_labels[self.connectors[1]].setPos(pos) |
394 |
elif self.name == 'HEX_H': |
395 |
if 'N1' in nozzles and 'N2' in nozzles: |
396 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
397 |
self.desc_labels[self.connectors[0]]) |
398 |
self.desc_labels[self.connectors[0]].setPos(pos) |
399 |
elif 'N1' in nozzles: |
400 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
401 |
self.desc_labels[self.connectors[0]]) |
402 |
self.desc_labels[self.connectors[0]].setPos(pos) |
403 |
elif 'N2' in nozzles: |
404 |
pos = self.get_label_pos_of_connector(self.connectors[1], |
405 |
self.desc_labels[self.connectors[1]]) |
406 |
self.desc_labels[self.connectors[1]].setPos(pos) |
407 |
elif self.name == 'HEX_K': |
408 |
if 'N1' in nozzles and 'N2' in nozzles: |
409 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
410 |
self.desc_labels[self.connectors[0]]) |
411 |
self.desc_labels[self.connectors[0]].setPos(pos) |
412 |
elif 'N1' in nozzles: |
413 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
414 |
self.desc_labels[self.connectors[0]]) |
415 |
self.desc_labels[self.connectors[0]].setPos(pos) |
416 |
elif 'N2' in nozzles: |
417 |
pos = self.get_label_pos_of_connector(self.connectors[1], |
418 |
self.desc_labels[self.connectors[1]]) |
419 |
self.desc_labels[self.connectors[1]].setPos(pos) |
420 |
elif self.name == 'HEX_P': |
421 |
if 'N1' in nozzles and 'N2' in nozzles: |
422 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
423 |
self.desc_labels[self.connectors[0]]) |
424 |
self.desc_labels[self.connectors[0]].setPos(pos) |
425 |
elif 'N1' in nozzles: |
426 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
427 |
self.desc_labels[self.connectors[0]]) |
428 |
self.desc_labels[self.connectors[0]].setPos(pos) |
429 |
elif 'N2' in nozzles: |
430 |
pos = self.get_label_pos_of_connector(self.connectors[1], |
431 |
self.desc_labels[self.connectors[1]]) |
432 |
self.desc_labels[self.connectors[1]].setPos(pos) |
433 |
elif self.name == 'HEX_V': |
434 |
if 'N1' in nozzles and 'N2' in nozzles: |
435 |
pos = self.get_label_pos_of_connector(self.connectors[2], |
436 |
self.desc_labels[self.connectors[2]]) |
437 |
self.desc_labels[self.connectors[2]].setPos(pos) |
438 |
elif 'N1' in nozzles: |
439 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
440 |
self.desc_labels[self.connectors[0]]) |
441 |
self.desc_labels[self.connectors[0]].setPos(pos) |
442 |
elif 'N2' in nozzles: |
443 |
pos = self.get_label_pos_of_connector(self.connectors[1], |
444 |
self.desc_labels[self.connectors[1]]) |
445 |
self.desc_labels[self.connectors[1]].setPos(pos) |
446 |
elif self.type == 'Miscellaneous': |
447 |
if self.name == 'M_Coil': |
448 |
if self.tag_no: |
449 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
450 |
if conns:
|
451 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
452 |
self.desc_labels[conns[0]].setPos(pos) |
453 |
elif self.name == 'M_DP_E': |
454 |
if self.tag_no: |
455 |
nozzles = [] |
456 |
for conn in self.connectors: |
457 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
458 |
nozzle = str(conn).rsplit('_', 1)[1] |
459 |
nozzles.append(nozzle) |
460 |
|
461 |
if len(nozzles) > 0: |
462 |
if 'N1' in nozzles and 'N2' in nozzles: |
463 |
label_rect = self.desc_labels[self.connectors[0]].boundingRect() |
464 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
465 |
self.desc_labels[self.connectors[0]]) |
466 |
self.desc_labels[self.connectors[0]].setPos(pos) |
467 |
elif 'N1' in nozzles: |
468 |
pos = self.get_label_pos_of_connector(self.connectors[0], |
469 |
self.desc_labels[self.connectors[0]]) |
470 |
self.desc_labels[self.connectors[0]].setPos(pos) |
471 |
elif 'N2' in nozzles: |
472 |
pos = self.get_label_pos_of_connector(self.connectors[1], |
473 |
self.desc_labels[self.connectors[1]]) |
474 |
self.desc_labels[self.connectors[1]].setPos(pos) |
475 |
elif self.name == 'M_React': |
476 |
if self.tag_no: |
477 |
nozzles = [] |
478 |
for conn in self.connectors: |
479 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
480 |
nozzle = str(conn).rsplit('_', 1)[1] |
481 |
nozzles.append(nozzle) |
482 |
|
483 |
if len(nozzles) > 0: |
484 |
if ('N1' in nozzles or 'N2' in nozzles or 'N6' in nozzles) and ('N3' in nozzles or 'N4' in nozzles or 'N5' in nozzles): |
485 |
if 'N1' in nozzles: |
486 |
top_index = 0
|
487 |
elif 'N2' in nozzles: |
488 |
top_index = 1
|
489 |
elif 'N6' in nozzles: |
490 |
top_index = 5
|
491 |
|
492 |
if 'N3' in nozzles: |
493 |
btm_index = 2
|
494 |
elif 'N4' in nozzles: |
495 |
btm_index = 3
|
496 |
elif 'N5' in nozzles: |
497 |
btm_index = 4
|
498 |
|
499 |
pos = self.get_label_pos_of_connector(self.connectors[top_index], |
500 |
self.desc_labels[self.connectors[top_index]]) |
501 |
self.desc_labels[self.connectors[top_index]].setPos(pos) |
502 |
|
503 |
elif 'N1' in nozzles or 'N2' in nozzles or 'N6' in nozzles: |
504 |
if 'N1' in nozzles: |
505 |
index = 0
|
506 |
elif 'N2' in nozzles: |
507 |
index = 1
|
508 |
elif 'N6' in nozzles: |
509 |
index = 5
|
510 |
|
511 |
pos = self.get_label_pos_of_connector(self.connectors[index], |
512 |
self.desc_labels[self.connectors[index]]) |
513 |
self.desc_labels[self.connectors[index]].setPos(pos) |
514 |
|
515 |
elif 'N3' in nozzles or 'N4' in nozzles or 'N5' in nozzles: |
516 |
if 'N3' in nozzles: |
517 |
index = 2
|
518 |
elif 'N4' in nozzles: |
519 |
index = 3
|
520 |
elif 'N5' in nozzles: |
521 |
index = 4
|
522 |
|
523 |
pos = self.get_label_pos_of_connector(self.connectors[index], |
524 |
self.desc_labels[self.connectors[index]]) |
525 |
self.desc_labels[self.connectors[index]].setPos(pos) |
526 |
elif self.type == 'Strainer': |
527 |
if self.tag_no: |
528 |
conns = [conn for conn in self.connectors |
529 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
530 |
if conns:
|
531 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
532 |
self.desc_labels[conns[0]].setPos(pos) |
533 |
elif self.category == 'Equipment - [ Pressurized ]': |
534 |
if self.type == 'Battery Limit': |
535 |
if self.tag_no: |
536 |
conns = [conn for conn in self.connectors |
537 |
if conn.data and conn.data.pressure is not None and conn.data.elevation is not None] |
538 |
if conns:
|
539 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
540 |
self.desc_labels[conns[0]].setPos(pos) |
541 |
elif self.type == 'Column': |
542 |
if self.tag_no: |
543 |
for conn in self.connectors: |
544 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
545 |
nozzle = str(conn).rsplit('_', 1)[1] |
546 |
pos = self.get_label_pos_of_connector(conn, self.desc_labels[conn]) |
547 |
self.desc_labels[conn].setPos(pos)
|
548 |
elif self.type == 'Drum': |
549 |
if self.tag_no: |
550 |
for conn in self.connectors: |
551 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
552 |
nozzle = str(conn).rsplit('_', 1)[1] |
553 |
pos = self.get_label_pos_of_connector(conn, self.desc_labels[conn]) |
554 |
self.desc_labels[conn].setPos(pos)
|
555 |
elif self.type == 'Miscellaneous': |
556 |
if self.tag_no: |
557 |
for conn in self.connectors: |
558 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
559 |
nozzle = str(conn).rsplit('_', 1)[1] |
560 |
if conn.data:
|
561 |
pos = self.get_label_pos_of_connector(conn, self.desc_labels[conn]) |
562 |
self.desc_labels[conn].setPos(pos)
|
563 |
elif self.type == 'Tank': |
564 |
if self.tag_no: |
565 |
for conn in self.connectors: |
566 |
if conn.data and conn.connectedItem and \ |
567 |
(conn.data.pressure_drop is not None or conn.data.elevation is not None): |
568 |
nozzle = str(conn).rsplit('_', 1)[1] |
569 |
pos = self.get_label_pos_of_connector(conn, self.desc_labels[conn]) |
570 |
self.desc_labels[conn].setPos(pos)
|
571 |
elif self.category == 'Equipment - [ Rotating ]': |
572 |
if self.type == 'Compressor': |
573 |
if self.name in ('L_Comp', 'R_Comp'): |
574 |
if self.tag_no: |
575 |
for conn in self.connectors: |
576 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
577 |
nozzle = str(conn).rsplit('_', 1)[1] |
578 |
pos = self.get_label_pos_of_connector(conn, self.desc_labels[conn]) |
579 |
self.desc_labels[conn].setPos(pos)
|
580 |
elif self.name in ('L_Komp', 'R_Komp'): |
581 |
if self.tag_no: |
582 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
583 |
if conns:
|
584 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
585 |
self.desc_labels[conns[0]].setPos(pos) |
586 |
elif self.type == 'Pump': |
587 |
if self.tag_no: |
588 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
589 |
if conns:
|
590 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
591 |
self.desc_labels[conns[0]].setPos(pos) |
592 |
elif self.category == 'Instrument': |
593 |
if self.type == 'Flowmeter': |
594 |
if self.tag_no: |
595 |
data = self.connectors[0].data |
596 |
if data:
|
597 |
pos = self.get_label_pos_of_connector(self.connectors[0], self.desc_labels[self.connectors[0]]) |
598 |
self.desc_labels[self.connectors[0]].setPos(pos) |
599 |
elif self.type == 'Line Splitter': |
600 |
if self.tag_no: |
601 |
conns = [conn for conn in self.connectors |
602 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
603 |
if conns:
|
604 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
605 |
self.desc_labels[conns[0]].setPos(pos) |
606 |
elif self.type == 'Reducer': |
607 |
if self.tag_no: |
608 |
conns = [conn for conn in self.connectors |
609 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
610 |
if conns:
|
611 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
612 |
self.desc_labels[conns[0]].setPos(pos) |
613 |
elif self.type == 'Valve': |
614 |
if self.tag_no and self.name in ('CV_H', 'CV_V'): |
615 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
616 |
if conns:
|
617 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
618 |
self.desc_labels[conns[0]].setPos(pos) |
619 |
elif self.tag_no and self.name in ('MV_H', 'MV_V'): |
620 |
conns = [conn for conn in self.connectors |
621 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
622 |
if conns:
|
623 |
pos = self.get_label_pos_of_connector(conns[0], self.desc_labels[conns[0]]) |
624 |
self.desc_labels[conns[0]].setPos(pos) |
625 |
|
626 |
configs = app_doc_data.getAppConfigs('option', 'TagFontSize') |
627 |
font_size = configs[0].value if configs and len(configs) == 1 else '6' |
628 |
|
629 |
configs = app_doc_data.getAppConfigs('option', 'TagFontColor') |
630 |
font_color = configs[0].value if configs and len(configs) == 1 else '#000000' |
631 |
|
632 |
for conn, label in self.desc_labels.items(): |
633 |
label.set_font_size(font_size) |
634 |
label.set_font_color(font_color) |
635 |
|
636 |
self.align_labels()
|
637 |
except Exception as ex: |
638 |
from App import App |
639 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
640 |
sys.exc_info()[-1].tb_lineno)
|
641 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
642 |
|
643 |
def align_labels(self) -> None: |
644 |
"""align labels which has same direction"""
|
645 |
|
646 |
sides = {} |
647 |
matches = [(conn.dir(), label) for conn, label in self.desc_labels.items() if label.toPlainText()] |
648 |
for dir, label in matches: |
649 |
if dir in sides: |
650 |
sides[dir].append(label)
|
651 |
else:
|
652 |
sides[dir] = [label]
|
653 |
|
654 |
for dir, labels in sides.items(): |
655 |
if len(labels) > 1: |
656 |
|
657 |
# sort labels
|
658 |
if dir[0] == 1 or dir[0] == -1: |
659 |
sorted_labels = sorted(labels, key=lambda label: label.sceneBoundingRect().top()) |
660 |
else:
|
661 |
sorted_labels = sorted(labels, key=lambda label: label.sceneBoundingRect().left()) |
662 |
# up to here
|
663 |
|
664 |
for i in range(len(sorted_labels)): |
665 |
for j in range(i + 1, len(sorted_labels)): |
666 |
if sorted_labels[i].collidesWithItem(sorted_labels[j]):
|
667 |
rect1 = sorted_labels[i].sceneBoundingRect() |
668 |
rect2 = sorted_labels[j].sceneBoundingRect() |
669 |
if dir[0] == 1 or dir[0] == -1: |
670 |
overlap = rect1.bottom() - rect2.top() |
671 |
pos = sorted_labels[i].pos() |
672 |
pos.setY(pos.y() - overlap*0.5)
|
673 |
sorted_labels[i].setPos(pos) |
674 |
pos = sorted_labels[j].pos() |
675 |
pos.setY(pos.y() + overlap*0.5)
|
676 |
sorted_labels[j].setPos(pos) |
677 |
else:
|
678 |
overlap = rect1.right() - rect2.left() |
679 |
pos = sorted_labels[i].pos() |
680 |
pos.setX(pos.x() - overlap*0.5)
|
681 |
sorted_labels[i].setPos(pos) |
682 |
pos = sorted_labels[j].pos() |
683 |
pos.setX(pos.x() + overlap*0.5)
|
684 |
sorted_labels[j].setPos(pos) |
685 |
|
686 |
def update_label_contents(self) -> None: |
687 |
"""update equipment label contents"""
|
688 |
|
689 |
rect = self.boundingRect()
|
690 |
|
691 |
try:
|
692 |
app_doc_data = AppDocData.instance() |
693 |
units = [attr[1] for attr in app_doc_data.activeDrawing.attrs if attr[0] == 'Units'][0] |
694 |
|
695 |
# clear labels
|
696 |
for conn, label in self.desc_labels.items(): |
697 |
"""reset all of nozzle descriptions"""
|
698 |
if conn.data:
|
699 |
conn.data.desc = None
|
700 |
label.setEnabled(False)
|
701 |
|
702 |
if self.category == 'Equipment - [ Pressure Drop ]': |
703 |
if self.type == 'Air Fin Cooler': |
704 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
705 |
if conns:
|
706 |
if conns[0].data.desc is None: |
707 |
self.desc_labels[conns[0]].setHtml( |
708 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop) if conns[0].data.pressure_drop is not None else 0} {units['Pressure']}<br>"
|
709 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
710 |
else:
|
711 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
712 |
self.desc_labels[conns[0]].setEnabled(True) |
713 |
elif self.type == 'Filter': |
714 |
if self.tag_no: |
715 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
716 |
if conns:
|
717 |
if conns[0].data.desc is None: |
718 |
self.desc_labels[conns[0]].setHtml( |
719 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop) if conns[0].data.pressure_drop is not None else 0} {units['Pressure']}<br>"
|
720 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
721 |
else:
|
722 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
723 |
|
724 |
self.desc_labels[conns[0]].setEnabled(True) |
725 |
elif self.type == 'Heat Exchanger': |
726 |
if self.tag_no: |
727 |
nozzles = [] |
728 |
for conn in self.connectors: |
729 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
730 |
nozzle = str(conn).rsplit('_', 1)[1] |
731 |
nozzles.append(nozzle) |
732 |
|
733 |
if len(nozzles) > 0: |
734 |
if self.name == 'HEX_DP': |
735 |
if 'N1' in nozzles and 'N2' in nozzles: |
736 |
if self.connectors[0].data.desc is None: |
737 |
self.desc_labels[self.connectors[0]].setHtml( |
738 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} [T] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
739 |
f"[S] : {convert_to_fixed_point(self.connectors[1].data.elevation)} [T] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
740 |
else:
|
741 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
742 |
|
743 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
744 |
elif 'N1' in nozzles: |
745 |
if self.connectors[0].data.desc is None: |
746 |
self.desc_labels[self.connectors[0]].setHtml( |
747 |
f"{self.tag_no}<br>[T] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
748 |
f"[T] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
749 |
else:
|
750 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
751 |
|
752 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
753 |
elif 'N2' in nozzles: |
754 |
if self.connectors[1].data.desc is None: |
755 |
self.desc_labels[self.connectors[1]].setHtml( |
756 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
757 |
f"[S] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
758 |
else:
|
759 |
self.desc_labels[self.connectors[1]].setHtml(self.connectors[1].data.desc) |
760 |
|
761 |
self.desc_labels[self.connectors[1]].setEnabled(True) |
762 |
elif self.name == 'HEX_H': |
763 |
if 'N1' in nozzles and 'N2' in nozzles: |
764 |
if self.connectors[0].data.desc is None: |
765 |
self.desc_labels[self.connectors[0]].setHtml( |
766 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} [T] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
767 |
f"[S] : {convert_to_fixed_point(self.connectors[0].data.elevation)} [T] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
768 |
else:
|
769 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
770 |
|
771 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
772 |
elif 'N1' in nozzles: |
773 |
if self.connectors[0].data.desc is None: |
774 |
self.desc_labels[self.connectors[0]].setHtml( |
775 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
776 |
f"[S] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
777 |
else:
|
778 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
779 |
|
780 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
781 |
elif 'N2' in nozzles: |
782 |
if self.connectors[1].data.desc is None: |
783 |
self.desc_labels[self.connectors[1]].setHtml( |
784 |
f"{self.tag_no}<br>[T] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
785 |
f"[T] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
786 |
else:
|
787 |
self.desc_labels[self.connectors[1]].setHtml(self.connectors[1].data.desc) |
788 |
|
789 |
self.desc_labels[self.connectors[1]].setEnabled(True) |
790 |
elif self.name == 'HEX_K': |
791 |
if 'N1' in nozzles and 'N2' in nozzles: |
792 |
if self.connectors[0].data.desc is None: |
793 |
self.desc_labels[self.connectors[0]].setHtml( |
794 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} [T] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
795 |
f"[S] : {convert_to_fixed_point(self.connectors[1].data.elevation)} [T] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
796 |
else:
|
797 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
798 |
|
799 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
800 |
elif 'N1' in nozzles: |
801 |
if self.connectors[0].data.desc is None: |
802 |
self.desc_labels[self.connectors[0]].setHtml( |
803 |
f"{self.tag_no}<br>[T] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
804 |
f"[T] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
805 |
else:
|
806 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
807 |
|
808 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
809 |
elif 'N2' in nozzles: |
810 |
if self.connectors[1].data.desc is None: |
811 |
self.desc_labels[self.connectors[1]].setHtml( |
812 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
813 |
f"[S] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
814 |
else:
|
815 |
self.desc_labels[self.connectors[1]].setHtml(self.connectors[1].data.desc) |
816 |
|
817 |
self.desc_labels[self.connectors[1]].setEnabled(True) |
818 |
elif self.name == 'HEX_P': |
819 |
if 'N1' in nozzles and 'N2' in nozzles: |
820 |
if self.connectors[0].data.desc is None: |
821 |
self.desc_labels[self.connectors[0]].setHtml( |
822 |
f"{self.tag_no}<br>[A] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} [B] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
823 |
f"[A] : {convert_to_fixed_point(self.connectors[0].data.elevation)} [B] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
824 |
else:
|
825 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
826 |
|
827 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
828 |
elif 'N1' in nozzles: |
829 |
if self.connectors[0].data.desc is None: |
830 |
self.desc_labels[self.connectors[0]].setHtml( |
831 |
f"{self.tag_no}<br>[A] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
832 |
f"[A] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
833 |
else:
|
834 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
835 |
|
836 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
837 |
elif 'N2' in nozzles: |
838 |
if self.connectors[1].data.desc is None: |
839 |
self.desc_labels[self.connectors[1]].setHtml( |
840 |
f"{self.tag_no}<br>[B] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
841 |
f"[B] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
842 |
else:
|
843 |
self.desc_labels[self.connectors[1]].setHtml(self.connectors[1].data.desc) |
844 |
|
845 |
self.desc_labels[self.connectors[1]].setEnabled(True) |
846 |
elif self.name == 'HEX_V': |
847 |
if 'N1' in nozzles and 'N2' in nozzles: |
848 |
if self.connectors[0].data.desc is None: |
849 |
self.desc_labels[self.connectors[0]].setHtml( |
850 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} [T] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
851 |
f"[S] : {convert_to_fixed_point(self.connectors[1].data.elevation)} [T] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
852 |
else:
|
853 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
854 |
|
855 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
856 |
elif 'N1' in nozzles: |
857 |
if self.connectors[0].data.desc is None: |
858 |
self.desc_labels[self.connectors[0]].setHtml( |
859 |
f"{self.tag_no}<br>[T] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
860 |
f"[T] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
861 |
else:
|
862 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
863 |
|
864 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
865 |
elif 'N2' in nozzles: |
866 |
if self.connectors[1].data.desc is None: |
867 |
self.desc_labels[self.connectors[1]].setHtml( |
868 |
f"{self.tag_no}<br>[S] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
869 |
f"[S] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
870 |
else:
|
871 |
self.desc_labels[self.connectors[1]].setHtml(self.connectors[1].data.desc) |
872 |
|
873 |
self.desc_labels[self.connectors[1]].setEnabled(True) |
874 |
elif self.type == 'Miscellaneous': |
875 |
if self.name == 'M_Coil': |
876 |
if self.tag_no: |
877 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
878 |
if conns:
|
879 |
if conns[0].data.desc is None: |
880 |
self.desc_labels[conns[0]].setHtml( |
881 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop) if conns[0].data.pressure_drop is not None else 0} {units['Pressure']}<br>"
|
882 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
883 |
else:
|
884 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
885 |
|
886 |
self.desc_labels[conns[0]].setEnabled(True) |
887 |
elif self.name == 'M_DP_E': |
888 |
if self.tag_no: |
889 |
nozzles = [] |
890 |
for conn in self.connectors: |
891 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
892 |
nozzle = str(conn).rsplit('_', 1)[1] |
893 |
nozzles.append(nozzle) |
894 |
|
895 |
if len(nozzles) > 0: |
896 |
if 'N1' in nozzles and 'N2' in nozzles: |
897 |
if self.connectors[0].data.desc is None: |
898 |
self.desc_labels[self.connectors[0]].setHtml( |
899 |
f"{self.tag_no}<br>[H] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} [V] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
900 |
f"[H] : {convert_to_fixed_point(self.connectors[1].data.elevation)} [V] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
901 |
else:
|
902 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
903 |
|
904 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
905 |
elif 'N1' in nozzles: |
906 |
if self.connectors[0].data.desc is None: |
907 |
self.desc_labels[self.connectors[0]].setHtml( |
908 |
f"{self.tag_no}<br>[V] : {convert_to_fixed_point(self.connectors[0].data.pressure_drop)} {units['Pressure']}<br>"
|
909 |
f"[V] : {convert_to_fixed_point(self.connectors[0].data.elevation)} {units['Length']}")
|
910 |
else:
|
911 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
912 |
|
913 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
914 |
elif 'N2' in nozzles: |
915 |
if self.connectors[1].data.desc is None: |
916 |
self.desc_labels[self.connectors[1]].setHtml( |
917 |
f"{self.tag_no}<br>[H] : {convert_to_fixed_point(self.connectors[1].data.pressure_drop)} {units['Pressure']}<br>"
|
918 |
f"[H] : {convert_to_fixed_point(self.connectors[1].data.elevation)} {units['Length']}")
|
919 |
else:
|
920 |
self.desc_labels[self.connectors[1]].setHtml(self.connectors[1].data.desc) |
921 |
|
922 |
self.desc_labels[self.connectors[1]].setEnabled(True) |
923 |
elif self.name == 'M_React': |
924 |
if self.tag_no: |
925 |
nozzles = [] |
926 |
for conn in self.connectors: |
927 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
928 |
nozzle = str(conn).rsplit('_', 1)[1] |
929 |
nozzles.append(nozzle) |
930 |
|
931 |
if len(nozzles) > 0: |
932 |
if ('N1' in nozzles or 'N2' in nozzles or 'N6' in nozzles) and \ |
933 |
('N3' in nozzles or 'N4' in nozzles or 'N5' in nozzles): |
934 |
if 'N1' in nozzles: |
935 |
top_index = 0
|
936 |
elif 'N2' in nozzles: |
937 |
top_index = 1
|
938 |
elif 'N6' in nozzles: |
939 |
top_index = 5
|
940 |
|
941 |
if 'N3' in nozzles: |
942 |
btm_index = 2
|
943 |
elif 'N4' in nozzles: |
944 |
btm_index = 3
|
945 |
elif 'N5' in nozzles: |
946 |
btm_index = 4
|
947 |
|
948 |
if self.connectors[top_index].data.desc is None: |
949 |
self.desc_labels[self.connectors[top_index]].setHtml( |
950 |
f"[DP] : {convert_to_fixed_point(self.connectors[top_index].data.pressure_drop)} {units['Pressure']}<br>"
|
951 |
f"[Top] : {convert_to_fixed_point(self.connectors[top_index].data.elevation)} {units['Length']}<br>"
|
952 |
f"[Btm] : {convert_to_fixed_point(self.connectors[btm_index].data.elevation)} {units['Length']}")
|
953 |
else:
|
954 |
self.desc_labels[self.connectors[top_index]].setHtml(self.connectors[top_index].data.desc) |
955 |
|
956 |
self.desc_labels[self.connectors[top_index]].setEnabled(True) |
957 |
elif 'N1' in nozzles or 'N2' in nozzles or 'N6' in nozzles: |
958 |
if 'N1' in nozzles: |
959 |
index = 0
|
960 |
elif 'N2' in nozzles: |
961 |
index = 1
|
962 |
elif 'N6' in nozzles: |
963 |
index = 5
|
964 |
|
965 |
if self.connectors[index].data.desc is None: |
966 |
self.desc_labels[self.connectors[index]].setHtml( |
967 |
f"[DP] : {convert_to_fixed_point(self.connectors[index].data.pressure_drop)} {units['Pressure']}<br>"
|
968 |
f"[Top] : {convert_to_fixed_point(self.connectors[index].data.elevation)} {units['Length']}")
|
969 |
else:
|
970 |
self.desc_labels[self.connectors[index]].setHtml(self.connectors[index].data.desc) |
971 |
|
972 |
self.desc_labels[self.connectors[index]].setEnabled(True) |
973 |
elif 'N3' in nozzles or 'N4' in nozzles or 'N5' in nozzles: |
974 |
if 'N3' in nozzles: |
975 |
index = 2
|
976 |
elif 'N4' in nozzles: |
977 |
index = 3
|
978 |
elif 'N5' in nozzles: |
979 |
index = 4
|
980 |
|
981 |
if self.connectors[index].data.desc is None: |
982 |
self.desc_labels[self.connectors[index]].setHtml( |
983 |
f"[DP] : {convert_to_fixed_point(self.connectors[index].data.pressure_drop)} {units['Pressure']}<br>"
|
984 |
f"[Btm] : {convert_to_fixed_point(self.connectors[index].data.elevation)} {units['Length']}")
|
985 |
else:
|
986 |
self.desc_labels[self.connectors[index]].setHtml(self.connectors[index].data.desc) |
987 |
|
988 |
self.desc_labels[self.connectors[index]].setEnabled(True) |
989 |
elif self.type == 'Strainer': |
990 |
if self.tag_no: |
991 |
conns = [conn for conn in self.connectors |
992 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
993 |
if conns:
|
994 |
if conns[0].data.desc is None: |
995 |
self.desc_labels[conns[0]].setHtml( |
996 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop)} {units['Pressure']}<br>"
|
997 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
998 |
else:
|
999 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1000 |
|
1001 |
self.desc_labels[conns[0]].setEnabled(True) |
1002 |
elif self.category == 'Equipment - [ Pressurized ]': |
1003 |
if self.type == 'Battery Limit': |
1004 |
if self.tag_no: |
1005 |
conns = [conn for conn in self.connectors |
1006 |
if conn.data and conn.data.pressure is not None and conn.data.elevation is not None] |
1007 |
if conns:
|
1008 |
if conns[0].data.desc is None: |
1009 |
self.desc_labels[conns[0]].setHtml( |
1010 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure)} {units['Pressure']}(g)<br>"
|
1011 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1012 |
else:
|
1013 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1014 |
|
1015 |
self.desc_labels[conns[0]].setEnabled(True) |
1016 |
elif self.type == 'Column': |
1017 |
if self.tag_no: |
1018 |
for conn in self.connectors: |
1019 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
1020 |
nozzle = str(conn).rsplit('_', 1)[1] |
1021 |
if conn.data.desc is None: |
1022 |
self.desc_labels[conn].setHtml(
|
1023 |
f"{self.tag_no}_{nozzle}<br>{convert_to_fixed_point(conn.data.pressure)} "
|
1024 |
f"{units['Pressure']}(g)<br>{convert_to_fixed_point(conn.data.elevation)} {units['Length']}")
|
1025 |
else:
|
1026 |
self.desc_labels[conn].setHtml(conn.data.desc)
|
1027 |
|
1028 |
self.desc_labels[conn].setEnabled(True) |
1029 |
elif self.type == 'Drum': |
1030 |
if self.tag_no: |
1031 |
for conn in self.connectors: |
1032 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
1033 |
nozzle = str(conn).rsplit('_', 1)[1] |
1034 |
if conn.data.desc is None: |
1035 |
self.desc_labels[conn].setHtml(
|
1036 |
f"{self.tag_no}_{nozzle}<br>{convert_to_fixed_point(conn.data.pressure)} "
|
1037 |
f"{units['Pressure']}(g)<br>{convert_to_fixed_point(conn.data.elevation)} {units['Length']}")
|
1038 |
else:
|
1039 |
self.desc_labels[conn].setHtml(conn.data.desc)
|
1040 |
|
1041 |
self.desc_labels[conn].setEnabled(True) |
1042 |
elif self.type == 'Miscellaneous': |
1043 |
if self.tag_no: |
1044 |
for conn in self.connectors: |
1045 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
1046 |
nozzle = str(conn).rsplit('_', 1)[1] |
1047 |
if conn.data:
|
1048 |
if conn.data.desc is None: |
1049 |
self.desc_labels[conn].setHtml(
|
1050 |
f"{self.tag_no}_{nozzle}<br>{convert_to_fixed_point(conn.data.pressure)} "
|
1051 |
f"{units['Pressure']}(g)<br>{convert_to_fixed_point(conn.data.elevation)} {units['Length']}")
|
1052 |
else:
|
1053 |
self.desc_labels[conn].setHtml(conn.data.desc)
|
1054 |
|
1055 |
self.desc_labels[conn].setEnabled(True) |
1056 |
elif self.type == 'Tank': |
1057 |
if self.tag_no: |
1058 |
for conn in self.connectors: |
1059 |
if conn.data and conn.connectedItem and \ |
1060 |
(conn.data.pressure_drop is not None or conn.data.elevation is not None): |
1061 |
nozzle = str(conn).rsplit('_', 1)[1] |
1062 |
if conn.data.desc is None: |
1063 |
self.desc_labels[conn].setHtml(
|
1064 |
f"{self.tag_no}_{nozzle}<br>{convert_to_fixed_point(conn.data.pressure)} "
|
1065 |
f"{units['Pressure']}(g)<br>{convert_to_fixed_point(conn.data.elevation)} {units['Length']}")
|
1066 |
else:
|
1067 |
self.desc_labels[conn].setHtml(conn.data.desc)
|
1068 |
|
1069 |
self.desc_labels[conn].setEnabled(True) |
1070 |
elif self.category == 'Equipment - [ Rotating ]': |
1071 |
if self.type == 'Compressor': |
1072 |
if self.name in ('L_Comp', 'R_Comp'): |
1073 |
if self.tag_no: |
1074 |
for conn in self.connectors: |
1075 |
if conn.data and (conn.data.pressure_drop is not None or conn.data.elevation is not None): |
1076 |
nozzle = str(conn).rsplit('_', 1)[1] |
1077 |
if conn.data.desc is None: |
1078 |
self.desc_labels[conn].setHtml(
|
1079 |
f"{self.tag_no}_{nozzle}<br>{convert_to_fixed_point(conn.data.pressure)} "
|
1080 |
f"{units['Pressure']}(g)<br>{convert_to_fixed_point(conn.data.elevation)} {units['Length']}")
|
1081 |
else:
|
1082 |
self.desc_labels[conn].setHtml(conn.data.desc)
|
1083 |
|
1084 |
self.desc_labels[conn].setEnabled(True) |
1085 |
elif self.name in ('L_Komp', 'R_Komp'): |
1086 |
if self.tag_no: |
1087 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
1088 |
if conns:
|
1089 |
if conns[0].data.desc is None: |
1090 |
self.desc_labels[conns[0]].setHtml( |
1091 |
f"{self.tag_no}<br>"
|
1092 |
f"{convert_to_fixed_point(conns[0].data.pressure_drop) if conns[0].data.pressure_drop is not None else 0} {units['Pressure']}<br>"
|
1093 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1094 |
else:
|
1095 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1096 |
|
1097 |
self.desc_labels[conns[0]].setEnabled(True) |
1098 |
elif self.type == 'Pump': |
1099 |
if self.tag_no: |
1100 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
1101 |
if conns:
|
1102 |
if conns[0].data.desc is None: |
1103 |
self.desc_labels[conns[0]].setHtml( |
1104 |
f"{self.tag_no}<br>"
|
1105 |
f"{convert_to_fixed_point(conns[0].data.pressure_drop) if conns[0].data.pressure_drop is not None else 0} {units['Pressure']}<br>"
|
1106 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1107 |
else:
|
1108 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1109 |
|
1110 |
self.desc_labels[conns[0]].setEnabled(True) |
1111 |
elif self.category == 'Instrument': |
1112 |
if self.type == 'Flowmeter': |
1113 |
if self.tag_no: |
1114 |
data = self.connectors[0].data |
1115 |
if data:
|
1116 |
if self.connectors[0].data.desc is None: |
1117 |
self.desc_labels[self.connectors[0]].setHtml( |
1118 |
f"{self.tag_no}<br>{convert_to_fixed_point(data.pressure_drop)} "
|
1119 |
f"{units['Pressure']}<br>{convert_to_fixed_point(data.elevation)} {units['Length']}")
|
1120 |
else:
|
1121 |
self.desc_labels[self.connectors[0]].setHtml(self.connectors[0].data.desc) |
1122 |
|
1123 |
self.desc_labels[self.connectors[0]].setEnabled(True) |
1124 |
elif self.type == 'Line Splitter': |
1125 |
if self.tag_no: |
1126 |
conns = [conn for conn in self.connectors |
1127 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
1128 |
if conns:
|
1129 |
if conns[0].data.desc is None: |
1130 |
self.desc_labels[conns[0]].setHtml( |
1131 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop)} "
|
1132 |
f"{units['Pressure']}<br>{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1133 |
else:
|
1134 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1135 |
|
1136 |
self.desc_labels[conns[0]].setEnabled(True) |
1137 |
elif self.type == 'Reducer': |
1138 |
if self.tag_no: |
1139 |
conns = [conn for conn in self.connectors |
1140 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
1141 |
if conns:
|
1142 |
if conns[0].data.desc is None: |
1143 |
self.desc_labels[conns[0]].setHtml( |
1144 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop)} "
|
1145 |
f"{units['Pressure']}<br>{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1146 |
else:
|
1147 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1148 |
|
1149 |
self.desc_labels[conns[0]].setEnabled(True) |
1150 |
elif self.type == 'Valve': |
1151 |
if self.tag_no and self.name in ('CV_H', 'CV_V'): |
1152 |
conns = [conn for conn in self.connectors if conn.data and conn.data.elevation is not None] |
1153 |
if conns:
|
1154 |
if conns[0].data.desc is None: |
1155 |
self.desc_labels[conns[0]].setHtml( |
1156 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop) if conns[0].data.pressure_drop is not None else 0} {units['Pressure']}<br>"
|
1157 |
f"{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1158 |
else:
|
1159 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1160 |
|
1161 |
self.desc_labels[conns[0]].setEnabled(True) |
1162 |
elif self.tag_no and self.name in ('MV_H', 'MV_V'): |
1163 |
conns = [conn for conn in self.connectors |
1164 |
if conn.data and conn.data.pressure_drop is not None and conn.data.elevation is not None] |
1165 |
if conns:
|
1166 |
if conns[0].data.desc is None: |
1167 |
self.desc_labels[conns[0]].setHtml( |
1168 |
f"{self.tag_no}<br>{convert_to_fixed_point(conns[0].data.pressure_drop)} "
|
1169 |
f"{units['Pressure']}<br>{convert_to_fixed_point(conns[0].data.elevation)} {units['Length']}")
|
1170 |
else:
|
1171 |
self.desc_labels[conns[0]].setHtml(conns[0].data.desc) |
1172 |
|
1173 |
self.desc_labels[conns[0]].setEnabled(True) |
1174 |
|
1175 |
configs = app_doc_data.getAppConfigs('option', 'TagFontSize') |
1176 |
font_size = configs[0].value if configs and len(configs) == 1 else '6' |
1177 |
|
1178 |
configs = app_doc_data.getAppConfigs('option', 'TagFontColor') |
1179 |
font_color = configs[0].value if configs and len(configs) == 1 else '#000000' |
1180 |
|
1181 |
for conn, label in self.desc_labels.items(): |
1182 |
label.set_font_size(font_size) |
1183 |
label.set_font_color(font_color) |
1184 |
label.setHtml(label.toPlainText().replace('\n', '<br>')) |
1185 |
except Exception as ex: |
1186 |
from App import App |
1187 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
1188 |
f"{sys.exc_info()[-1].tb_lineno}"
|
1189 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1190 |
|
1191 |
def rect(self): |
1192 |
"""return bounding box of symbol"""
|
1193 |
return self.sceneBoundingRect() |
1194 |
|
1195 |
'''
|
1196 |
@brief return true if line is able to connect symbol
|
1197 |
@author humkyung
|
1198 |
@date 2018.04.13
|
1199 |
'''
|
1200 |
|
1201 |
def is_connectable(self, item, toler=10): |
1202 |
# from EngineeringLineItem import QEngineeringLineItem
|
1203 |
|
1204 |
'''
|
1205 |
if False:#type(item) is QEngineeringLineItem:
|
1206 |
line = item
|
1207 |
start_pt = line.startPoint()
|
1208 |
end_pt = line.endPoint()
|
1209 |
for connector in self.connectors:
|
1210 |
dx = connector.sceneConnectPoint[0] - (start_pt[0])
|
1211 |
dy = connector.sceneConnectPoint[1] - (start_pt[1])
|
1212 |
if (math.sqrt(dx*dx + dy*dy) < toler): return True
|
1213 |
dx = connector.sceneConnectPoint[0] - (end_pt[0])
|
1214 |
dy = connector.sceneConnectPoint[1] - (end_pt[1])
|
1215 |
if (math.sqrt(dx*dx + dy*dy) < toler): return True
|
1216 |
elif True:#issubclass(type(item), SymbolSvgItem):
|
1217 |
'''
|
1218 |
for connector in self.connectors: |
1219 |
for iConnector in item.connectors: |
1220 |
dx = connector.sceneConnectPoint[0] - iConnector.sceneConnectPoint[0] |
1221 |
dy = connector.sceneConnectPoint[1] - iConnector.sceneConnectPoint[1] |
1222 |
if (math.sqrt(dx * dx + dy * dy) < toler): return True |
1223 |
|
1224 |
return False |
1225 |
|
1226 |
'''
|
1227 |
@author humkyung
|
1228 |
@date 2018.07.03
|
1229 |
'''
|
1230 |
|
1231 |
def is_connected(self, item, at=QEngineeringAbstractItem.CONNECTED_AT_PT): |
1232 |
""" check if given item is connected to self """
|
1233 |
|
1234 |
_connectors = [connector for connector in self.connectors if |
1235 |
(connector.connectedItem == item and (connector._connected_at == at if at else True))] |
1236 |
return len(_connectors) > 0 |
1237 |
|
1238 |
def getConnectionPointCloseTo(self, pt, toler=10): |
1239 |
"""get connection point close to given point in tolerance"""
|
1240 |
import math |
1241 |
|
1242 |
for connector in self.connectors: |
1243 |
center = connector.center() |
1244 |
|
1245 |
dx = center[0] - pt[0] |
1246 |
dy = center[1] - pt[1] |
1247 |
|
1248 |
if math.sqrt(dx * dx + dy * dy) < toler:
|
1249 |
return center
|
1250 |
|
1251 |
return None |
1252 |
|
1253 |
'''
|
1254 |
@brief return center of symbol
|
1255 |
@author humkyung
|
1256 |
@date 2018.04.08
|
1257 |
'''
|
1258 |
|
1259 |
def center(self): |
1260 |
return self.sceneBoundingRect().center() |
1261 |
|
1262 |
def hoverEnterEvent(self, event): |
1263 |
self.highlight(True) |
1264 |
|
1265 |
'''
|
1266 |
@brief unhighlight connector and attribute
|
1267 |
@author humkyung
|
1268 |
@date 2018.05.02
|
1269 |
@history kyouho 2018.07.18 edit ArrowCursor
|
1270 |
'''
|
1271 |
|
1272 |
def hoverLeaveEvent(self, event): |
1273 |
self.highlight(False) |
1274 |
|
1275 |
def highlight(self, flag): |
1276 |
""" highlight/unhighlight the symbol """
|
1277 |
|
1278 |
try:
|
1279 |
self.hover = flag
|
1280 |
self.setZValue(QEngineeringAbstractItem.HOVER_ZVALUE) if flag else self.setZValue(SymbolSvgItem.ZVALUE) |
1281 |
self.update()
|
1282 |
except Exception as ex: |
1283 |
from App import App |
1284 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1285 |
sys.exc_info()[-1].tb_lineno)
|
1286 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1287 |
|
1288 |
'''
|
1289 |
@brief set highlight
|
1290 |
@author kyouho
|
1291 |
@date 2018.08.27
|
1292 |
'''
|
1293 |
|
1294 |
def setHightlight(self): |
1295 |
self.setColor('url(#hover)') |
1296 |
self.update()
|
1297 |
|
1298 |
'''
|
1299 |
@brief unset highlight
|
1300 |
@author kyouho
|
1301 |
@date 2018.08.27
|
1302 |
'''
|
1303 |
|
1304 |
def unsetHightlight(self): |
1305 |
self.setColor('url(#normal)') |
1306 |
self.update()
|
1307 |
|
1308 |
def get_selected_corner(self, pos): |
1309 |
toler = 5 * self.scale() |
1310 |
|
1311 |
corner = self.corners[2] |
1312 |
dx = corner.x() - pos.x() |
1313 |
dy = corner.y() - pos.y() |
1314 |
return math.sqrt(dx * dx + dy * dy) < toler
|
1315 |
|
1316 |
def mousePressEvent(self, event): |
1317 |
import math |
1318 |
|
1319 |
if event.buttons() == Qt.LeftButton:
|
1320 |
toler = 5*self.scale() |
1321 |
|
1322 |
# try to select corner
|
1323 |
pos = event.scenePos() |
1324 |
corner = self.corners[2] |
1325 |
dx = corner.x() - pos.x() |
1326 |
dy = corner.y() - pos.y() |
1327 |
self._selected_idx = 2 if math.sqrt(dx * dx + dy * dy) < toler else None |
1328 |
# up to here
|
1329 |
|
1330 |
super(SymbolSvgItem, self).mousePressEvent(event) |
1331 |
|
1332 |
def mouseMoveEvent(self, event): |
1333 |
"""reshape dimension"""
|
1334 |
|
1335 |
if event.buttons() == Qt.LeftButton and self._selected_idx is not None: |
1336 |
corners = [event.scenePos(), self.corners[(self._selected_idx + 2) % 4]] |
1337 |
min_x, min_y = min(corners, key=lambda pt: pt.x()).x(), min(corners, key=lambda pt: pt.y()).y() |
1338 |
max_x, max_y = max(corners, key=lambda pt: pt.x()).x(), max(corners, key=lambda pt: pt.y()).y() |
1339 |
|
1340 |
self.resize(QRectF(min_x, min_y, max_x - min_x, max_y - min_y))
|
1341 |
return
|
1342 |
|
1343 |
super(SymbolSvgItem, self).mouseMoveEvent(event) |
1344 |
|
1345 |
def mouseReleaseEvent(self, event): |
1346 |
self._selected_idx = None |
1347 |
super(SymbolSvgItem, self).mouseReleaseEvent(event) |
1348 |
|
1349 |
def itemChange(self, change, value): |
1350 |
""" call signals when item's position is changed """
|
1351 |
if change == QGraphicsItem.ItemPositionHasChanged or change == QGraphicsItem.ItemScaleHasChanged: |
1352 |
self.transfer.on_pos_changed.emit(self) |
1353 |
self.scene().contents_changed.emit()
|
1354 |
return value
|
1355 |
|
1356 |
return super().itemChange(change, value) |
1357 |
|
1358 |
def keyPressEvent(self, event): |
1359 |
"""key event handler"""
|
1360 |
if not self.isSelected(): return |
1361 |
|
1362 |
if event.key() == Qt.Key_Delete:
|
1363 |
self.deleteSvgItemFromScene()
|
1364 |
elif event.key() == Qt.Key_QuoteLeft:
|
1365 |
self.mouseDoubleClickEvent(event)
|
1366 |
elif event.key() == Qt.Key_H:
|
1367 |
from FlipCommand import FlipCommand |
1368 |
|
1369 |
try:
|
1370 |
viewer = App.mainWnd().graphicsView |
1371 |
items = viewer.scene.selectedItems() |
1372 |
if items:
|
1373 |
viewer.scene.undo_stack.push(FlipCommand(viewer.scene, items, flip=1))
|
1374 |
except Exception as ex: |
1375 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
1376 |
f"{sys.exc_info()[-1].tb_lineno}"
|
1377 |
|
1378 |
self.addMessage.emit(MessageType.Error, message)
|
1379 |
elif event.key() == Qt.Key_V:
|
1380 |
from FlipCommand import FlipCommand |
1381 |
|
1382 |
try:
|
1383 |
viewer = App.mainWnd().graphicsView |
1384 |
items = viewer.scene.selectedItems() |
1385 |
if items:
|
1386 |
viewer.scene.undo_stack.push(FlipCommand(viewer.scene, items, flip=2))
|
1387 |
except Exception as ex: |
1388 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
1389 |
f"{sys.exc_info()[-1].tb_lineno}"
|
1390 |
|
1391 |
self.addMessage.emit(MessageType.Error, message)
|
1392 |
|
1393 |
|
1394 |
'''
|
1395 |
@brief Double click event, Show rotate symbol dialog
|
1396 |
@author euisung
|
1397 |
@date 2019.04.16
|
1398 |
'''
|
1399 |
|
1400 |
def mouseDoubleClickEvent(self, event): |
1401 |
func_map = [ |
1402 |
(('Equipment - [ Pressure Drop ]', 'Air Fin Cooler', 'AF_Cooler'), self.show_AirFinCooler), |
1403 |
(('Equipment - [ Pressure Drop ]', 'Filter', ('Filter_H', 'Filter_V')), self.show_Filter), |
1404 |
(('Equipment - [ Pressure Drop ]', 'Heat Exchanger', ('HEX_DP', 'HEX_H', 'HEX_K', 'HEX_V')), |
1405 |
self.show_ShlTubHeatExchanger),
|
1406 |
(('Equipment - [ Pressure Drop ]', 'Heat Exchanger', ('HEX_P')), self.show_PlateHeatExchanger), |
1407 |
(('Equipment - [ Pressure Drop ]', 'Miscellaneous', ('M_Coil')), self.show_Coil), |
1408 |
(('Equipment - [ Pressure Drop ]', 'Miscellaneous', ('M_DP_E')), self.show_DP_Equipment), |
1409 |
(('Equipment - [ Pressure Drop ]', 'Miscellaneous', ('M_React')), self.show_Reactor), |
1410 |
(('Equipment - [ Pressure Drop ]', 'Strainer', ('T_Strainer_H', 'T_Strainer_V')), self.show_Strainer_T), |
1411 |
(('Equipment - [ Pressure Drop ]', 'Strainer', ('Y_Strainer_H', 'Y_Strainer_V')), self.show_Strainer_Y), |
1412 |
(('Equipment - [ Pressurized ]', 'Battery Limit', None), self.show_BatteryLimit), |
1413 |
(('Equipment - [ Pressurized ]', 'Column', ('CwT')), self.show_Tray), |
1414 |
(('Equipment - [ Pressurized ]', 'Column', ('CwP_Single')), self.show_SinglePacked), |
1415 |
(('Equipment - [ Pressurized ]', 'Column', ('CwP_Dual')), self.show_DualPacked), |
1416 |
(('Equipment - [ Pressurized ]', 'Drum', ('Drum_H')), self.show_Drum_Horizontal), |
1417 |
(('Equipment - [ Pressurized ]', 'Drum', ('Drum_V')), self.show_Drum_Vertical), |
1418 |
(('Equipment - [ Pressurized ]', 'Miscellaneous', ('ME')), self.show_Equipment), |
1419 |
(('Equipment - [ Pressurized ]', 'Tank', ('Ball_Tank')), self.show_Ball), |
1420 |
(('Equipment - [ Pressurized ]', 'Tank', ('CRT')), self.show_ConeRoof), |
1421 |
(('Equipment - [ Pressurized ]', 'Tank', ('DRT')), self.show_DomeRoof), |
1422 |
(('Equipment - [ Rotating ]', 'Compressor', ('L_Comp', 'R_Comp')), self.show_Compressor), |
1423 |
(('Equipment - [ Rotating ]', 'Compressor', ('L_Komp', 'R_Komp')), self.show_Kompressor), |
1424 |
(('Equipment - [ Rotating ]', 'Pump', ('L_Pump', 'R_Pump', 'V_Pump')), self.show_Pump), |
1425 |
(('Instrument', 'Valve', ('CV_H', 'CV_V')), self.show_ValveControl), |
1426 |
(('Instrument', 'Valve', ('MV_H', 'MV_V')), self.show_ValveManual), |
1427 |
(('Instrument', 'Line Splitter', ('Line_Splitter')), self.show_LineSplitter), |
1428 |
(('Instrument', 'Flowmeter', ( |
1429 |
'Ori_Flowmeter_H', 'Oth_Flowmeter_H', 'Ven_Flowmeter_H', 'Ori_Flowmeter_V', 'Oth_Flowmeter_V', |
1430 |
'Ven_Flowmeter_V')), self.show_Flowmeter), |
1431 |
(('Instrument', 'Reducer', ('Re_Ex_Dw', 'Re_Ex_L', 'Re_Ex_R', 'Re_Ex_Up')), self.show_Reducer) |
1432 |
] |
1433 |
|
1434 |
connectedItems = [connector for connector in self.connectors if connector.connectedItem is not None] |
1435 |
if len(connectedItems) < 1: |
1436 |
msg = QMessageBox() |
1437 |
msg.setIcon(QMessageBox.Information) |
1438 |
msg.setText(self.tr('Connect Line before Data input')) |
1439 |
msg.setWindowTitle(self.tr("Information")) |
1440 |
msg.setStandardButtons(QMessageBox.Ok) |
1441 |
msg.exec_() |
1442 |
return
|
1443 |
|
1444 |
matches = [func for func in func_map if func[0][0] == self.category and func[0][1] == self.type and |
1445 |
(func[0][2] is None or self.name in func[0][2])] |
1446 |
if matches:
|
1447 |
matches[0][1]() |
1448 |
|
1449 |
def change_output_font_color(self): |
1450 |
|
1451 |
App.mainWnd().change_output_font_color() |
1452 |
|
1453 |
'''
|
1454 |
row_count = App.mainWnd().tableWidgetDeviation.rowCount()
|
1455 |
col_count = App.mainWnd().tableWidgetDeviation.columnCount()
|
1456 |
for row in range(row_count):
|
1457 |
for col in range(col_count):
|
1458 |
if row == 0:
|
1459 |
item = App.mainWnd().tableWidgetDeviation.item(row, col)
|
1460 |
item.setText('RUN CALCULATION')
|
1461 |
item.setForeground(Qt.red)
|
1462 |
App.mainWnd().tableWidgetDeviation.setItem(row, col, item)
|
1463 |
else:
|
1464 |
App.mainWnd().tableWidgetDeviation.item(row, col).setForeground(QBrush(QColor(169, 169, 169)))
|
1465 |
|
1466 |
row_count = App.mainWnd().tableWidgetOutput.rowCount()
|
1467 |
col_count = App.mainWnd().tableWidgetOutput.columnCount()
|
1468 |
for row in range(row_count):
|
1469 |
for col in range(col_count):
|
1470 |
App.mainWnd().tableWidgetOutput.item(row, col).setForeground(QBrush(QColor(169, 169, 169)))
|
1471 |
col_span = App.mainWnd().tableWidgetOutput.columnSpan(row, col)
|
1472 |
if col_span > 1:
|
1473 |
break
|
1474 |
'''
|
1475 |
|
1476 |
def show_AirFinCooler(self): |
1477 |
from AirFinCooler import QAirFinCooler |
1478 |
|
1479 |
dialog = QAirFinCooler() |
1480 |
modified = dialog.show_dialog(self)
|
1481 |
if modified:
|
1482 |
self.update_label_contents()
|
1483 |
self.validate()
|
1484 |
self.change_output_font_color()
|
1485 |
|
1486 |
def show_Filter(self): |
1487 |
from Filter import QFilter |
1488 |
|
1489 |
dialog = QFilter() |
1490 |
modified = dialog.show_dialog(self)
|
1491 |
if modified:
|
1492 |
self.update_label_contents()
|
1493 |
self.validate()
|
1494 |
self.change_output_font_color()
|
1495 |
|
1496 |
def show_Coil(self): |
1497 |
from Coil import QCoil |
1498 |
|
1499 |
dialog = QCoil() |
1500 |
modified = dialog.show_dialog(self)
|
1501 |
if modified:
|
1502 |
self.update_label_contents()
|
1503 |
self.validate()
|
1504 |
self.change_output_font_color()
|
1505 |
|
1506 |
def show_DP_Equipment(self): |
1507 |
from DP_Equipment import QDP_Equipment |
1508 |
|
1509 |
dialog = QDP_Equipment() |
1510 |
modified = dialog.show_dialog(self)
|
1511 |
if modified:
|
1512 |
self.update_label_contents()
|
1513 |
self.validate()
|
1514 |
self.change_output_font_color()
|
1515 |
|
1516 |
def show_Reactor(self): |
1517 |
from Reactor import QReactor |
1518 |
|
1519 |
dialog = QReactor() |
1520 |
modified = dialog.show_dialog(self)
|
1521 |
if modified:
|
1522 |
self.update_label_contents()
|
1523 |
self.validate()
|
1524 |
self.change_output_font_color()
|
1525 |
|
1526 |
def show_Strainer_T(self): |
1527 |
from Strainer_T import QStrainer_T |
1528 |
|
1529 |
dialog = QStrainer_T() |
1530 |
modified = dialog.show_dialog(self)
|
1531 |
if modified:
|
1532 |
self.update_label_contents()
|
1533 |
self.validate()
|
1534 |
self.change_output_font_color()
|
1535 |
|
1536 |
def show_Strainer_Y(self): |
1537 |
from Strainer_Y import QStrainer_Y |
1538 |
|
1539 |
dialog = QStrainer_Y() |
1540 |
modified = dialog.show_dialog(self)
|
1541 |
if modified:
|
1542 |
self.update_label_contents()
|
1543 |
self.validate()
|
1544 |
self.change_output_font_color()
|
1545 |
|
1546 |
def show_BatteryLimit(self): |
1547 |
from BatteryLimit import QBatteryLimit |
1548 |
|
1549 |
dialog = QBatteryLimit() |
1550 |
modified = dialog.show_dialog(self)
|
1551 |
if modified:
|
1552 |
self.update_label_contents()
|
1553 |
self.validate()
|
1554 |
self.change_output_font_color()
|
1555 |
|
1556 |
def show_Tray(self): |
1557 |
from Tray import QTray |
1558 |
|
1559 |
dialog = QTray() |
1560 |
modified = dialog.show_dialog(self)
|
1561 |
if modified:
|
1562 |
self.update_label_contents()
|
1563 |
self.validate()
|
1564 |
self.change_output_font_color()
|
1565 |
|
1566 |
def show_SinglePacked(self): |
1567 |
from SinglePacked import QSinglePacked |
1568 |
|
1569 |
dialog = QSinglePacked() |
1570 |
modified = dialog.show_dialog(self)
|
1571 |
if modified:
|
1572 |
self.update_label_contents()
|
1573 |
self.validate()
|
1574 |
self.change_output_font_color()
|
1575 |
|
1576 |
def show_DualPacked(self): |
1577 |
from DualPacked import QDualPacked |
1578 |
|
1579 |
dialog = QDualPacked() |
1580 |
modified = dialog.show_dialog(self)
|
1581 |
if modified:
|
1582 |
self.update_label_contents()
|
1583 |
self.validate()
|
1584 |
self.change_output_font_color()
|
1585 |
|
1586 |
def show_Drum_Horizontal(self): |
1587 |
from Drum_Horizontal import QDrum_Horizontal |
1588 |
|
1589 |
dialog = QDrum_Horizontal() |
1590 |
modified = dialog.show_dialog(self)
|
1591 |
if modified:
|
1592 |
self.update_label_contents()
|
1593 |
self.validate()
|
1594 |
self.change_output_font_color()
|
1595 |
|
1596 |
def show_Drum_Vertical(self): |
1597 |
from Drum_Vertical import QDrum_Vertical |
1598 |
|
1599 |
dialog = QDrum_Vertical() |
1600 |
modified = dialog.show_dialog(self)
|
1601 |
if modified:
|
1602 |
self.update_label_contents()
|
1603 |
self.validate()
|
1604 |
self.change_output_font_color()
|
1605 |
|
1606 |
def show_PlateHeatExchanger(self): |
1607 |
from PlateHeatExchanger import QPlateHeatExchanger |
1608 |
|
1609 |
dialog = QPlateHeatExchanger() |
1610 |
modified = dialog.show_dialog(self)
|
1611 |
if modified:
|
1612 |
self.update_label_contents()
|
1613 |
self.validate()
|
1614 |
self.change_output_font_color()
|
1615 |
|
1616 |
def show_Equipment(self): |
1617 |
from Equipment import QEquipment |
1618 |
|
1619 |
dialog = QEquipment() |
1620 |
modified = dialog.show_dialog(self)
|
1621 |
if modified:
|
1622 |
self.update_label_contents()
|
1623 |
self.validate()
|
1624 |
self.change_output_font_color()
|
1625 |
|
1626 |
def show_Ball(self): |
1627 |
from Ball import QBall |
1628 |
|
1629 |
dialog = QBall() |
1630 |
modified = dialog.show_dialog(self)
|
1631 |
if modified:
|
1632 |
self.update_label_contents()
|
1633 |
self.validate()
|
1634 |
self.change_output_font_color()
|
1635 |
|
1636 |
def show_ShlTubHeatExchanger(self): |
1637 |
from ShlTubHeatExchanger import QShlTubHeatExchanger |
1638 |
|
1639 |
dialog = QShlTubHeatExchanger() |
1640 |
modified = dialog.show_dialog(self)
|
1641 |
if modified:
|
1642 |
self.update_label_contents()
|
1643 |
self.validate()
|
1644 |
self.change_output_font_color()
|
1645 |
|
1646 |
def show_ConeRoof(self): |
1647 |
from ConeRoof import QConeRoof |
1648 |
|
1649 |
dialog = QConeRoof() |
1650 |
modified = dialog.show_dialog(self)
|
1651 |
if modified:
|
1652 |
self.update_label_contents()
|
1653 |
self.validate()
|
1654 |
self.change_output_font_color()
|
1655 |
|
1656 |
def show_DomeRoof(self): |
1657 |
from DomeRoof import QDomeRoof |
1658 |
|
1659 |
dialog = QDomeRoof() |
1660 |
modified = dialog.show_dialog(self)
|
1661 |
if modified:
|
1662 |
self.update_label_contents()
|
1663 |
self.validate()
|
1664 |
self.change_output_font_color()
|
1665 |
|
1666 |
def show_Compressor(self): |
1667 |
from Compressor import QCompressor |
1668 |
|
1669 |
dialog = QCompressor() |
1670 |
modified = dialog.show_dialog(self)
|
1671 |
if modified:
|
1672 |
self.update_label_contents()
|
1673 |
self.validate()
|
1674 |
self.change_output_font_color()
|
1675 |
|
1676 |
def show_Kompressor(self): |
1677 |
from Kompressor import QKompressor |
1678 |
|
1679 |
dialog = QKompressor() |
1680 |
modified = dialog.show_dialog(self)
|
1681 |
if modified:
|
1682 |
self.update_label_contents()
|
1683 |
self.validate()
|
1684 |
self.change_output_font_color()
|
1685 |
|
1686 |
def show_Pump(self): |
1687 |
from Pump import QPump |
1688 |
|
1689 |
dialog = QPump() |
1690 |
modified = dialog.show_dialog(self)
|
1691 |
if modified:
|
1692 |
self.update_label_contents()
|
1693 |
self.validate()
|
1694 |
self.change_output_font_color()
|
1695 |
|
1696 |
def show_ValveControl(self): |
1697 |
from Valve_Control import QValve_Control |
1698 |
|
1699 |
dialog = QValve_Control() |
1700 |
modified = dialog.show_dialog(self)
|
1701 |
if modified:
|
1702 |
self.update_label_contents()
|
1703 |
self.validate()
|
1704 |
self.change_output_font_color()
|
1705 |
|
1706 |
def show_ValveManual(self): |
1707 |
from Valve_Manual import QValve_Manual |
1708 |
|
1709 |
dialog = QValve_Manual() |
1710 |
modified = dialog.show_dialog(self)
|
1711 |
if modified:
|
1712 |
self.update_label_contents()
|
1713 |
self.validate()
|
1714 |
self.change_output_font_color()
|
1715 |
|
1716 |
def show_LineSplitter(self): |
1717 |
from LineSplitter import QLineSplitter |
1718 |
|
1719 |
dialog = QLineSplitter() |
1720 |
modified = dialog.show_dialog(self)
|
1721 |
if modified:
|
1722 |
self.update_label_contents()
|
1723 |
self.validate()
|
1724 |
self.change_output_font_color()
|
1725 |
|
1726 |
def show_Flowmeter(self): |
1727 |
from Flowmeter import QFlowmeter |
1728 |
|
1729 |
dialog = QFlowmeter() |
1730 |
modified = dialog.show_dialog(self)
|
1731 |
if modified:
|
1732 |
self.update_label_contents()
|
1733 |
self.validate()
|
1734 |
self.change_output_font_color()
|
1735 |
|
1736 |
def show_Reducer(self): |
1737 |
from Reducer import QReducer |
1738 |
|
1739 |
dialog = QReducer() |
1740 |
modified = dialog.show_dialog(self)
|
1741 |
if modified:
|
1742 |
self.update_label_contents()
|
1743 |
self.validate()
|
1744 |
self.change_output_font_color()
|
1745 |
|
1746 |
def rotate(self, angle: float) -> None: |
1747 |
"""rotate symbol clockwise by given angle in degree about origin point"""
|
1748 |
self.setRotation(angle)
|
1749 |
|
1750 |
@staticmethod
|
1751 |
def fromDatabase(componentInfos): |
1752 |
""" create a component from database """
|
1753 |
item = None
|
1754 |
|
1755 |
try:
|
1756 |
uid = componentInfos[0]['Comp_UID'] # uid@Components |
1757 |
tag_no = componentInfos[0]['Name'] # name@Components |
1758 |
index = componentInfos[0]['Comp_Index'] |
1759 |
dbUid = componentInfos[0]['Symbols_UID'] # Symbol_UID@Components |
1760 |
category = componentInfos[0]['Category'] # Category@SymbolType |
1761 |
_type = componentInfos[0]['Type'] # Type@SymbolType |
1762 |
name = componentInfos[0]['Symbol_Name'] # Name@Symbols |
1763 |
originalPoint = componentInfos[0]['OriginalPoint'] # OriginalPoint@Symbols |
1764 |
x = componentInfos[0]['Comp_X'] # X@Components |
1765 |
y = componentInfos[0]['Comp_Y'] # Y@Components |
1766 |
angle = componentInfos[0]['Rotation'] # Rotation@Components |
1767 |
#scale = componentInfos[0]['Scale'] # Scale@Components
|
1768 |
scales = [float(componentInfos[0]['ScaleX']), float(componentInfos[0]['ScaleY'])] # scale x, scale y |
1769 |
|
1770 |
pt = [] |
1771 |
pt.append(float(x))
|
1772 |
pt.append(float(y))
|
1773 |
|
1774 |
origin = [float(x) for x in str(originalPoint).split(',')] |
1775 |
|
1776 |
connPts = [] |
1777 |
|
1778 |
pointsUids = [] |
1779 |
for componentInfo in componentInfos: |
1780 |
pointsUid = componentInfo['Point_UID'] # uid@Points |
1781 |
pointsUids.append(pointsUid) |
1782 |
|
1783 |
item = SymbolSvgItem.createItem(_type, uid, None, 0, dbUid) |
1784 |
item.setVisible(False)
|
1785 |
item.buildItem(name, _type, float(angle), scales , pt, origin, connPts, dbUid, pointsUids, index)
|
1786 |
item.tag_no = tag_no |
1787 |
item.build_label() |
1788 |
|
1789 |
except Exception as ex: |
1790 |
from App import App |
1791 |
message = f'error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:' \
|
1792 |
f'{sys.exc_info()[-1].tb_lineno}'
|
1793 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1794 |
|
1795 |
return item
|
1796 |
|
1797 |
'''
|
1798 |
@brief create item corresponding to given type
|
1799 |
@author humkyung
|
1800 |
@date 2018.05.02
|
1801 |
@history 2018.05.08 Jeongwoo Change type name (Piping OPC''S → Piping OPC's)
|
1802 |
humkyung 2018.05.10 change symbol's color to blue
|
1803 |
humkyung 2018.07.19 create nozzle instance if type is 'Nozzles'
|
1804 |
'''
|
1805 |
|
1806 |
@staticmethod
|
1807 |
def createItem(type, uid=None, owner=None, flip=0, symbol=None): |
1808 |
import uuid |
1809 |
|
1810 |
item = SymbolSvgItem(uid, flip=flip, symbol=symbol) |
1811 |
|
1812 |
if owner is not None: |
1813 |
item.owner = uuid.UUID(owner) |
1814 |
|
1815 |
return item
|
1816 |
|
1817 |
'''
|
1818 |
@brief change svg's color
|
1819 |
@author humkyung
|
1820 |
@date 2018.05.10
|
1821 |
@history 2018.05.11 Jeongwoo Override QEngineeringAbstractItem's
|
1822 |
humkyung 2018.05.13 update after change color
|
1823 |
'''
|
1824 |
|
1825 |
def setColor(self, color): |
1826 |
self.changeAttributes('fill', color) |
1827 |
self.changeAttributes('stroke', color) |
1828 |
self.renderer().load(self._document.toByteArray()) |
1829 |
self.update()
|
1830 |
|
1831 |
def getColor(self): |
1832 |
""" return hover color if mouse is over otherwise reutrn owner's color if owner exist else this color """
|
1833 |
return SymbolSvgItem.HOVER_COLOR if self.hover else ( |
1834 |
self.owner._color if self.owner and hasattr(self.owner, '_color') else self._color) |
1835 |
|
1836 |
'''
|
1837 |
@brief get attributes from svg file
|
1838 |
@author humkyung
|
1839 |
@date 2019.03.08
|
1840 |
'''
|
1841 |
|
1842 |
def get_attribute(self, attName): |
1843 |
root = self._document.documentElement()
|
1844 |
node = root.firstChild() |
1845 |
while not node.isNull(): |
1846 |
if node.isElement():
|
1847 |
element = node.toElement() |
1848 |
if element.hasAttribute(attName):
|
1849 |
return element.attribute(attName)
|
1850 |
|
1851 |
if element.hasChildNodes():
|
1852 |
att_val = self.recursive_get_attribute(element.firstChild(), attName)
|
1853 |
if att_val is not None: return att_val |
1854 |
|
1855 |
node = node.nextSibling() |
1856 |
|
1857 |
return None |
1858 |
|
1859 |
'''
|
1860 |
@brief get recursively attribute
|
1861 |
@author humkyung
|
1862 |
@date 2019.03.08
|
1863 |
'''
|
1864 |
|
1865 |
def recursive_get_attribute(self, node, attName): |
1866 |
while not node.isNull(): |
1867 |
if node.isElement():
|
1868 |
element = node.toElement() |
1869 |
if element.hasAttribute(attName):
|
1870 |
return element.attribute(attName)
|
1871 |
|
1872 |
if node.hasChildNodes():
|
1873 |
att_val = self.recursive_get_attribute(node.firstChild(), attName)
|
1874 |
if att_val is not None: return att_val |
1875 |
|
1876 |
node = node.nextSibling() |
1877 |
|
1878 |
return None |
1879 |
|
1880 |
'''
|
1881 |
@brief change attributes
|
1882 |
@author humkyung
|
1883 |
@date 2018.05.10
|
1884 |
'''
|
1885 |
|
1886 |
def changeAttributes(self, attName, attValue): |
1887 |
root = self._document.documentElement()
|
1888 |
node = root.firstChild() |
1889 |
while not node.isNull(): |
1890 |
if node.isElement():
|
1891 |
element = node.toElement() |
1892 |
if element.hasAttribute(attName):
|
1893 |
element.setAttribute(attName, attValue) |
1894 |
|
1895 |
if element.hasChildNodes():
|
1896 |
recursiveChangeAttributes(element.firstChild(), attName, attValue) |
1897 |
|
1898 |
node = node.nextSibling() |
1899 |
|
1900 |
'''
|
1901 |
@brief change attribute
|
1902 |
@author humkyung
|
1903 |
@date 2018.05.10
|
1904 |
'''
|
1905 |
|
1906 |
def recursiveChangeAttributes(self, node, attName, attValue): |
1907 |
while not node.isNull(): |
1908 |
if node.isElement():
|
1909 |
element = node.toElement() |
1910 |
if element.hasAttribute(attName):
|
1911 |
element.setAttribute(attName, attValue) |
1912 |
|
1913 |
if node.hasChildNodes():
|
1914 |
recursiveChangeAttributes(node.firstChild(), attName, attValue) |
1915 |
|
1916 |
node = node.nextSibling() |
1917 |
|
1918 |
'''
|
1919 |
@brief draw rect when item is selected
|
1920 |
@author humkyung
|
1921 |
@date 2018.07.07
|
1922 |
'''
|
1923 |
|
1924 |
def draw_focus_rect(self, painter): |
1925 |
hilightColor = QColor(255, 0, 0, 127) |
1926 |
painter.setBrush(QBrush(hilightColor)) |
1927 |
|
1928 |
corner = self.corners[2] |
1929 |
pt = self.mapFromScene(corner)
|
1930 |
painter.drawEllipse(pt, 5, 5) |
1931 |
|
1932 |
def paint(self, painter, options=None, widget=None): |
1933 |
"""override paint(draw connection points)"""
|
1934 |
self.setColor(self.getColor()) |
1935 |
|
1936 |
painter.setClipRect(options.exposedRect) |
1937 |
QGraphicsSvgItem.paint(self, painter, options, widget)
|
1938 |
|
1939 |
if self.isSelected(): |
1940 |
self.draw_focus_rect(painter)
|
1941 |
|
1942 |
def addSvgItemToScene(self, scene): |
1943 |
"""add svg item to scene"""
|
1944 |
|
1945 |
try:
|
1946 |
scene.addItem(self)
|
1947 |
self.setTransformOriginPoint(QPointF(self.symbolOrigin[0], self.symbolOrigin[1])) # affect only to rotation |
1948 |
trans = QTransform() |
1949 |
trans.scale(self._scales[0], self._scales[1]) |
1950 |
self.setTransform(trans)
|
1951 |
self.rotate(self.angle) |
1952 |
pt = trans.map(self.symbolOrigin[0], self.symbolOrigin[1]) |
1953 |
self.setPos(self.loc[0] - pt[0], self.loc[1] - pt[1]) |
1954 |
|
1955 |
# scale down for label
|
1956 |
"""
|
1957 |
trans = QTransform()
|
1958 |
trans.scale(1 / self._scales[0], 1 / self._scales[1])
|
1959 |
for conn, label in self.desc_labels.items():
|
1960 |
label.setTransform(trans)
|
1961 |
"""
|
1962 |
# up to here
|
1963 |
except Exception as ex: |
1964 |
from App import App |
1965 |
from AppDocData import MessageType |
1966 |
|
1967 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
1968 |
f"{sys.exc_info()[-1].tb_lineno}"
|
1969 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1970 |
|
1971 |
'''
|
1972 |
@brief
|
1973 |
@author humkyung
|
1974 |
@date 2018.07.27
|
1975 |
'''
|
1976 |
|
1977 |
def onConnectorPosChaned(self, connector): |
1978 |
pass
|
1979 |
|
1980 |
def set_connector(self, uid, index=None): |
1981 |
"""set connector"""
|
1982 |
from AppDocData import AppDocData |
1983 |
|
1984 |
app_doc_data = AppDocData.instance() |
1985 |
connector = QEngineeringConnectorItem(uid, parent=self, index=index)
|
1986 |
connector.data = app_doc_data.get_nozzle_data(uid) |
1987 |
self.connectors.append(connector)
|
1988 |
|
1989 |
# set label
|
1990 |
label = QEngineeringEqpDescTextItem('', self) |
1991 |
self.desc_labels[connector] = label
|
1992 |
|
1993 |
def deleteSvgItemFromScene(self): |
1994 |
""" remove self from scene """
|
1995 |
try:
|
1996 |
for conn in self.connectors: |
1997 |
if conn.connectedItem is not None: |
1998 |
conn.connectedItem.connect(None)
|
1999 |
except Exception as ex: |
2000 |
from App import App |
2001 |
from AppDocData import MessageType |
2002 |
|
2003 |
message = f'error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:' \
|
2004 |
f'{sys.exc_info()[-1].tb_lineno}'
|
2005 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
2006 |
|
2007 |
self.transfer.onRemoved.emit(self) |
2008 |
|
2009 |
def flip_symbol(self, horizontal=True) -> None: |
2010 |
"""flip symbol"""
|
2011 |
trans = self.transform()
|
2012 |
rect = self.boundingRect()
|
2013 |
if horizontal: # horizontal flip |
2014 |
trans.scale(-1, 1) |
2015 |
trans.translate(-rect.width(), 0)
|
2016 |
else: # vertical flip |
2017 |
trans.scale(1, -1) |
2018 |
trans.translate(0, -rect.height())
|
2019 |
|
2020 |
self.resetTransform()
|
2021 |
self.setTransform(trans)
|
2022 |
|
2023 |
def getCurrentPoint(self): |
2024 |
"""get current point"""
|
2025 |
|
2026 |
pointList = [] |
2027 |
pointList.append(self.symbolOrigin)
|
2028 |
for connector in self.connectors: |
2029 |
pointList.append(connector.connectPoint) |
2030 |
|
2031 |
# if type(self) is QEngineeringSpecBreakItem:
|
2032 |
# self.currentPointModeIndex = 1
|
2033 |
|
2034 |
return pointList[self.currentPointModeIndex] |
2035 |
|
2036 |
'''
|
2037 |
@brief 심볼 회전 시 서로 다른 기준점으로 회전하기 때문에 기준점을 이후 개발한 SymbolSvgItem 기준의 회전좌표로 이동하기 위해서 만듬 (loc 기준으로 회전해야함)
|
2038 |
@author kyouho
|
2039 |
@date 18.08.06
|
2040 |
'''
|
2041 |
|
2042 |
def reCalculationRotatedItem(self): |
2043 |
|
2044 |
transform = QTransform() |
2045 |
transform.translate(self.loc[0] + self.symbolOrigin[0], self.loc[1] + self.symbolOrigin[1]) |
2046 |
transform.rotateRadians(-self.angle)
|
2047 |
currentPoint = self.getCurrentPoint()
|
2048 |
transform.translate(-currentPoint[0], -currentPoint[1]) |
2049 |
# 시작점을 구하기 위해서
|
2050 |
goPoint = transform.map(QPoint(self.symbolOrigin[0], self.symbolOrigin[1])) |
2051 |
|
2052 |
self.loc = [self.loc[0] + self.origin[0] - goPoint.x(), self.loc[1] + self.origin[1] - goPoint.y()] |
2053 |
|
2054 |
def moveto(self, to, timeLine=5000, rotation=0): |
2055 |
"""Move the item from one position to one other."""
|
2056 |
|
2057 |
anim = QPropertyAnimation(self, b'pos') |
2058 |
rect = self.sceneBoundingRect()
|
2059 |
anim.setStartValue(QPointF(0, 0)) |
2060 |
anim.setEndValue(QPointF(100, 10)) |
2061 |
anim.setDuration(10000)
|
2062 |
anim.start() |
2063 |
|
2064 |
|
2065 |
def recursiveChangeAttributes(node, attName, attValue): |
2066 |
while not node.isNull(): |
2067 |
if node.isElement():
|
2068 |
element = node.toElement() |
2069 |
if element.hasAttribute(attName):
|
2070 |
element.setAttribute(attName, attValue) |
2071 |
|
2072 |
if node.hasChildNodes():
|
2073 |
recursiveChangeAttributes(node.firstChild(), attName, attValue) |
2074 |
|
2075 |
node = node.nextSibling() |
2076 |
|
2077 |
|
2078 |
'''
|
2079 |
@brief The class transfer pyqtSignal Event. Cause Subclass of QGraphicsRectItem can't use pyqtSignal
|
2080 |
@author Jeongwoo
|
2081 |
@date 2018.06.18
|
2082 |
'''
|
2083 |
|
2084 |
|
2085 |
class Transfer(QObject): |
2086 |
on_pos_changed = pyqtSignal(QGraphicsItem) |
2087 |
on_size_changed = pyqtSignal(QGraphicsItem) |
2088 |
onRemoved = pyqtSignal(QGraphicsItem) |
2089 |
|
2090 |
def __init__(self, parent=None): |
2091 |
QObject.__init__(self, parent)
|
2092 |
|
2093 |
|
2094 |
if __name__ == '__main__': |
2095 |
f = QFile('d:/Projects/DTIPID/DTI_PID/DTI_PID/SG_TEST/svg/ANGLE VALVE.svg')
|
2096 |
f.open(QIODevice.ReadOnly) |
2097 |
array = f.readAll() |
2098 |
document = QDomDocument() |
2099 |
document.setContent(array) |
2100 |
|
2101 |
root = document.documentElement() |
2102 |
node = root.firstChild() |
2103 |
while not node.isNull(): |
2104 |
if node.isElement():
|
2105 |
element = node.toElement() |
2106 |
if element.hasAttribute('fill'): |
2107 |
element.setAttribute('fill', '#FFFFF') |
2108 |
|
2109 |
if element.hasChildNodes():
|
2110 |
recursiveChangeAttributes(element.firstChild(), 'fill', '#FFFFF') |
2111 |
|
2112 |
node = node.nextSibling() |