개정판 5c32058c
issue #1061: enable to resize symbol(revised)
Change-Id: I75d2e9fb31350dd44bb8026d497b714acbbb5f63
HYTOS/HYTOS/Commands/DefaultCommand.py | ||
---|---|---|
46 | 46 |
''' |
47 | 47 |
def execute(self, param): |
48 | 48 |
from SymbolSvgItem import SymbolSvgItem |
49 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
50 | 49 |
|
51 | 50 |
event = param[1] |
52 | 51 |
scenePos = param[2] |
HYTOS/HYTOS/MainWindow.py | ||
---|---|---|
30 | 30 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes') |
31 | 31 |
from SymbolSvgItem import SymbolSvgItem |
32 | 32 |
|
33 |
from EngineeringTextItem import QEngineeringTextItem |
|
34 | 33 |
from EngineeringErrorItem import QEngineeringErrorItem |
35 | 34 |
from EngineeringStreamlineItem import QEngineeringStreamlineItem |
36 | 35 |
from AppDocData import * |
HYTOS/HYTOS/QtImageViewer.py | ||
---|---|---|
16 | 16 |
import DefaultCommand |
17 | 17 |
|
18 | 18 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes') |
19 |
from EngineeringTextItem import QEngineeringTextItem |
|
20 | 19 |
from SymbolSvgItem import SymbolSvgItem |
21 | 20 |
|
22 | 21 |
__author__ = "Marcel Goldschen-Ohm <marcel.goldschen@gmail.com>" |
HYTOS/HYTOS/Shapes/EngineeringAbstractItem.py | ||
---|---|---|
170 | 170 |
|
171 | 171 |
return res |
172 | 172 |
|
173 |
def texts(self): |
|
174 |
""" return text type of associations """ |
|
175 |
from EngineeringTextItem import QEngineeringTextItem |
|
176 |
|
|
177 |
res = [] |
|
178 |
for text in [x for x in self.associations() if issubclass(type(x), QEngineeringTextItem)]: |
|
179 |
consumed = False |
|
180 |
for key in list(self.attrs.keys()): |
|
181 |
if key.AssocItem and key.AssocItem is text: |
|
182 |
consumed = True |
|
183 |
if not consumed: |
|
184 |
res.append(text) |
|
185 |
|
|
186 |
return res |
|
187 |
|
|
188 | 173 |
def symbols(self): |
189 | 174 |
""" return symbol type of associations """ |
190 | 175 |
from SymbolSvgItem import SymbolSvgItem |
... | ... | |
205 | 190 |
try: |
206 | 191 |
from AppDocData import AppDocData |
207 | 192 |
from SymbolSvgItem import SymbolSvgItem |
208 |
from EngineeringTextItem import QEngineeringTextItem |
|
209 | 193 |
from EngineeringLineItem import QEngineeringLineItem |
210 | 194 |
|
211 | 195 |
""" get attributes of item from database """ |
HYTOS/HYTOS/Shapes/EngineeringConnectorItem.py | ||
---|---|---|
389 | 389 |
import shapely |
390 | 390 |
from SymbolSvgItem import SymbolSvgItem |
391 | 391 |
from EngineeringArrowItem import QEngineeringArrowItem |
392 |
from EngineeringTextItem import QEngineeringTextItem |
|
393 | 392 |
|
394 | 393 |
try: |
395 | 394 |
if self.parentItem() is not None and self._savedPos is not None: |
HYTOS/HYTOS/Shapes/EngineeringLineNoTextItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is engineering line no text item module """ |
|
3 |
|
|
4 |
import os.path |
|
5 |
import sys |
|
6 |
import copy |
|
7 |
try: |
|
8 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
9 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
10 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem |
|
11 |
except ImportError: |
|
12 |
try: |
|
13 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
14 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
15 |
except ImportError: |
|
16 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
17 |
|
|
18 |
from EngineeringPolylineItem import QEngineeringPolylineItem |
|
19 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
|
20 |
from UserInputAttribute import UserInputAttribute |
|
21 |
from AppDocData import AppDocData |
|
22 |
from EngineeringTextItem import QEngineeringTextItem |
|
23 |
from TextInfo import TextInfo |
|
24 |
|
|
25 |
lineColumnList = ['UID', 'LINE_SIZE', 'LINE_SYMBOL', 'LINE_NO', 'LINE_CLASS', 'LINE_ROUTING_FROM', 'LINE_ROUTING_TO', 'SERVICE_FLUID', 'SERVICE_DENSITY', 'SERVICE_STATE', 'OPERATION_CONDITION_TEMP', 'OPERATION_CONDITION_PRESS', 'DESIGN_CONDITION_TEMP', 'DESIGN_CONDITION_PRESS', 'TEST_CONDITION_TEMP', 'TEST_CONDITION_PRESS', 'INSUL_CODE', 'PAINT_CODE', 'NDE_CODE', 'PWHT', 'PNID_NO'] |
|
26 |
|
|
27 |
class QEngineeringLineNoTextItem(QEngineeringTextItem): |
|
28 |
|
|
29 |
''' |
|
30 |
@history 18.05.14 Jeongwoo Add variable self.runs |
|
31 |
humkyung 2018.07.09 add stream no |
|
32 |
''' |
|
33 |
def __init__(self, uid=None, parent=None): |
|
34 |
from SymbolAttr import SymbolProp |
|
35 |
from EngineeringFreezeItem import QEngineeringFreezeItem |
|
36 |
|
|
37 |
QEngineeringTextItem.__init__(self, uid, parent) |
|
38 |
|
|
39 |
self._properties = {SymbolProp(None, 'From', 'Comp Item'):None, SymbolProp(None, 'To', 'Comp Item'):None, SymbolProp(None, 'Freeze', 'Boolean'):False} |
|
40 |
self._runs = [] |
|
41 |
|
|
42 |
""" create freeze control """ |
|
43 |
#self.freeze_item = QEngineeringFreezeItem(-QEngineeringFreezeItem.FREEZE_SIZE*0.5, -QEngineeringFreezeItem.FREEZE_SIZE*0.5, QEngineeringFreezeItem.FREEZE_SIZE, QEngineeringFreezeItem.FREEZE_SIZE) |
|
44 |
#self.freeze_item.setParentItem(self) |
|
45 |
#self.freeze_item.setZValue(self.zValue() + 1) |
|
46 |
#self.freeze_item.setPen(Qt.black) |
|
47 |
|
|
48 |
@property |
|
49 |
def properties(self): |
|
50 |
""" getter of properties """ |
|
51 |
import uuid |
|
52 |
|
|
53 |
for prop,value in self._properties.items(): |
|
54 |
if prop.is_selectable and type(value) is uuid.UUID and self.scene(): |
|
55 |
matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(value)] |
|
56 |
if matches: self._properties[prop] = matches[0] |
|
57 |
|
|
58 |
return self._properties |
|
59 |
|
|
60 |
@properties.setter |
|
61 |
def properties(self, value): |
|
62 |
""" setter of properties """ |
|
63 |
self._properties = value |
|
64 |
|
|
65 |
def prop(self, property): |
|
66 |
""" return property with given value """ |
|
67 |
matches = [prop for prop,_ in self.properties.items() if prop.Attribute == property] |
|
68 |
return self.properties[matches[0]] if matches else None |
|
69 |
|
|
70 |
def set_property(self, property, value): |
|
71 |
""" set property with given value """ |
|
72 |
matches = [prop for prop,_ in self._properties.items() if prop.Attribute == property] |
|
73 |
if matches: self._properties[matches[0]] = value |
|
74 |
|
|
75 |
@property |
|
76 |
def Size(self): |
|
77 |
""" return line no's size """ |
|
78 |
attrs = self.getAttributes() |
|
79 |
matches = [value for attr,value in attrs.items() if attr.Attribute.upper() == 'NOMINALDIAMETER'] |
|
80 |
return matches[0] if matches else None |
|
81 |
|
|
82 |
def empty(self): |
|
83 |
""" return True if run is empty else return False """ |
|
84 |
return False if self._runs else True |
|
85 |
|
|
86 |
def setVisible(self, visible): |
|
87 |
""" override visible value """ |
|
88 |
super(QEngineeringTextItem, self).setVisible(visible) |
|
89 |
for run in self.runs: |
|
90 |
run.visible = visible |
|
91 |
|
|
92 |
''' |
|
93 |
@brief getter of runs |
|
94 |
@author humkyung |
|
95 |
@date 2018.05.11 |
|
96 |
''' |
|
97 |
@property |
|
98 |
def runs(self): |
|
99 |
return self._runs |
|
100 |
|
|
101 |
''' |
|
102 |
@brief setter of runs |
|
103 |
@author humkyung |
|
104 |
@date 2018.05.11 |
|
105 |
''' |
|
106 |
@runs.setter |
|
107 |
def runs(self, value): |
|
108 |
self._runs = value |
|
109 |
|
|
110 |
def hoverEnterEvent(self, event): |
|
111 |
""" highlight line no text and run's item """ |
|
112 |
self.hover = True |
|
113 |
self.update() |
|
114 |
|
|
115 |
for run in self.runs: |
|
116 |
for item in run.items: |
|
117 |
item.hoverEnterEvent(event) |
|
118 |
|
|
119 |
def hoverLeaveEvent(self, event): |
|
120 |
""" unhighlight line no text and run's item """ |
|
121 |
self.hover = False |
|
122 |
self.update() |
|
123 |
|
|
124 |
for run in self.runs: |
|
125 |
for item in run.items: |
|
126 |
item.hoverLeaveEvent(event) |
|
127 |
|
|
128 |
def keyPressEvent(self, event): |
|
129 |
""" reverse line routine when user press 'C' key """ |
|
130 |
if event.key() == Qt.Key_C: |
|
131 |
self.reverse() |
|
132 |
|
|
133 |
""" |
|
134 |
def paint(self, painter, options=None, widget=None): |
|
135 |
QEngineeringTextItem.paint(self, painter, options, widget) |
|
136 |
if self.freeze_item is None: |
|
137 |
from EngineeringFreezeItem import QEngineeringFreezeItem |
|
138 |
|
|
139 |
self.freeze_item = QEngineeringFreezeItem(0, 0, QEngineeringFreezeItem.FREEZE_SIZE, QEngineeringFreezeItem.FREEZE_SIZE) |
|
140 |
self.freeze_item.setParentItem(self) |
|
141 |
self.freeze_item.setZValue(self.zValue() + 1) |
|
142 |
self.freeze_item.setPen(Qt.black) |
|
143 |
""" |
|
144 |
|
|
145 |
def reverse(self): |
|
146 |
""" reverse line routine """ |
|
147 |
|
|
148 |
if self.runs: |
|
149 |
self.runs[0].reverse() |
|
150 |
_from = self.prop('From') |
|
151 |
_to = self.prop('To') |
|
152 |
self.set_property('From', _to) |
|
153 |
self.set_property('To', _from) |
|
154 |
|
|
155 |
def getLongestTwoPoints(self, pts): |
|
156 |
import math |
|
157 |
res = [None, None] |
|
158 |
|
|
159 |
maxDistance = None |
|
160 |
for i in range(len(pts)): |
|
161 |
for j in range(i+1, len(pts)): |
|
162 |
dx = pts[i][0] - pts[j][0] |
|
163 |
dy = pts[i][1] - pts[j][1] |
|
164 |
dist = math.sqrt(dx*dx + dy*dy) |
|
165 |
if (maxDistance is None) or (maxDistance < dist): |
|
166 |
maxDistance = dist |
|
167 |
res[0] = pts[i] |
|
168 |
res[1] = pts[j] |
|
169 |
|
|
170 |
return res |
|
171 |
|
|
172 |
''' |
|
173 |
@brief set attribute |
|
174 |
@author humkyung |
|
175 |
@date 2018.07.20 |
|
176 |
''' |
|
177 |
def set_attrib(self, attrib, value): |
|
178 |
matches = [attr for attr in self.attrs if attr.UID == attrib.UID] |
|
179 |
if len(matches) == 1: |
|
180 |
self.attrs[matches[0]] = value |
|
181 |
else: |
|
182 |
self.attrs[attrib] = value |
|
183 |
|
|
184 |
def removeSelfAttr(self, attributeName): |
|
185 |
pass |
|
186 |
|
|
187 |
''' |
|
188 |
@brief get attribute |
|
189 |
@author kyouho |
|
190 |
@date 2018.09.06 |
|
191 |
''' |
|
192 |
def getAttributes(self): |
|
193 |
from SymbolAttr import SymbolAttr |
|
194 |
from Configs import LineNoConfig |
|
195 |
|
|
196 |
_attrs = {} |
|
197 |
try: |
|
198 |
docData = AppDocData.instance() |
|
199 |
|
|
200 |
line_no_configs = LineNoConfig.instance() |
|
201 |
config = None |
|
202 |
if line_no_configs: |
|
203 |
for line_no_config in line_no_configs: |
|
204 |
item = line_no_config.parse(self.text()) |
|
205 |
if item[0]: |
|
206 |
config = line_no_config |
|
207 |
break |
|
208 |
else: |
|
209 |
item = (False,) |
|
210 |
|
|
211 |
# Line No 부분 |
|
212 |
if item[0]: |
|
213 |
attr = SymbolAttr() |
|
214 |
attr.Attribute = 'LINE NO' |
|
215 |
attr.DisplayAttribute = 'Line No' |
|
216 |
attr.AttributeType = 'String' |
|
217 |
_attrs[attr] = self.text() |
|
218 |
|
|
219 |
result = item[1] |
|
220 |
configs = config.value.split(self.delimiter) |
|
221 |
props = docData.getLineProperties() |
|
222 |
for prop in props: |
|
223 |
if prop.UID in configs: |
|
224 |
for i in range(len(configs)): |
|
225 |
if prop.UID == configs[i]: |
|
226 |
_attrs[prop] = result[i] |
|
227 |
break |
|
228 |
else: |
|
229 |
matches = [attr for attr in self.attrs if attr.UID == prop.UID] |
|
230 |
if len(matches) == 1: |
|
231 |
_attrs[matches[0]] = self.attrs[matches[0]] |
|
232 |
else: |
|
233 |
_attrs[prop] = '' |
|
234 |
|
|
235 |
# attrs['CONN'] = self.conns[0].uid if self.conns else '' |
|
236 |
except Exception as ex: |
|
237 |
from App import App |
|
238 |
from AppDocData import MessageType |
|
239 |
|
|
240 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
241 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
242 |
|
|
243 |
return _attrs |
|
244 |
|
|
245 |
def end_break(self): |
|
246 |
''' |
|
247 |
@brief end break check |
|
248 |
@author euisung |
|
249 |
@date 2019.05.07 |
|
250 |
@history 2019.05.19 euisung can cover at both end that contact other line's middle |
|
251 |
2019.05.19 euisung no more used integrated with linetracer |
|
252 |
''' |
|
253 |
from EngineeringLineItem import QEngineeringLineItem |
|
254 |
from SymbolSvgItem import SymbolSvgItem |
|
255 |
from AppDocData import AppDocData |
|
256 |
end_breaks = [] |
|
257 |
|
|
258 |
try: |
|
259 |
docdata = AppDocData.instance() |
|
260 |
|
|
261 |
line_from = self.prop('From') |
|
262 |
line_to = self.prop('To') |
|
263 |
|
|
264 |
end_break_names = docdata.getSymbolListByType('type', 'End Break') |
|
265 |
if len(end_break_names) is 0: |
|
266 |
return end_breaks |
|
267 |
|
|
268 |
svgFileName = end_break_names[0].sName |
|
269 |
symbol = AppDocData.instance().getSymbolByQuery('name', svgFileName) |
|
270 |
svgFilePath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), symbol.getCategory(), symbol.getType(), svgFileName+'.svg') |
|
271 |
|
|
272 |
for line_end in [line_from, line_to]: |
|
273 |
for connector in line_end.connectors: |
|
274 |
if connector.connectedItem is not None and connector.connectedItem.owner is not self: |
|
275 |
end_break = SymbolSvgItem.createItem(symbol.getType()) |
|
276 |
pt = [connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
|
277 |
origin = [0,0] |
|
278 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
|
279 |
tokens = symbol.getOriginalPoint().split(',') |
|
280 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
|
281 |
end_break.buildItem(svgFileName, symbol.getType(), 5.7, pt, [end_break.boundingRect().width(), end_break.boundingRect().height()], origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel()) |
|
282 |
|
|
283 |
end_break.set_property('Connected Item', connector.connectedItem) |
|
284 |
end_break.setToolTip('owner : ' + str(line_end)) |
|
285 |
end_break.area = 'Drawing' |
|
286 |
end_break.owner = line_end |
|
287 |
end_breaks.append(end_break) |
|
288 |
|
|
289 |
except Exception as ex: |
|
290 |
from App import App |
|
291 |
from AppDocData import MessageType |
|
292 |
|
|
293 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
294 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
295 |
|
|
296 |
return end_breaks |
|
297 |
|
|
298 |
''' |
|
299 |
@Override (QEngineeringTextItem) |
|
300 |
@brief get connected items |
|
301 |
@author Jeongwoo |
|
302 |
@date 2018.05.15 |
|
303 |
''' |
|
304 |
def getConnectedItems(self): |
|
305 |
visited = [] |
|
306 |
|
|
307 |
try: |
|
308 |
for run in self.runs: |
|
309 |
visited.extend(run.items) |
|
310 |
except Exception as ex: |
|
311 |
from App import App |
|
312 |
from AppDocData import MessageType |
|
313 |
|
|
314 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
315 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
316 |
|
|
317 |
return visited |
|
318 |
|
|
319 |
def explode(self, remainFromTo=False): |
|
320 |
""" explode line no """ |
|
321 |
|
|
322 |
if False == self.prop('Freeze'): |
|
323 |
try: |
|
324 |
for index in reversed(range(len(self.runs))): |
|
325 |
self.runs[index].explode() |
|
326 |
finally: |
|
327 |
self.runs.clear() |
|
328 |
if not remainFromTo: |
|
329 |
self.set_property('From', None) |
|
330 |
self.set_property('To', None) |
|
331 |
|
|
332 |
''' |
|
333 |
@brief save Line Data |
|
334 |
@author kyouho |
|
335 |
@date 2018.08.14 |
|
336 |
''' |
|
337 |
def toSql(self): |
|
338 |
data = self.getLineDataList() |
|
339 |
sql = "insert or replace into LINE_DATA_LIST(UID, LINE_SIZE, LINE_SYMBOL, LINE_NO, LINE_CLASS, LINE_ROUTING_FROM, LINE_ROUTING_TO, SERVICE_FLUID, SERVICE_DENSITY, SERVICE_STATE, OPERATION_CONDITION_TEMP, OPERATION_CONDITION_PRESS, DESIGN_CONDITION_TEMP, DESIGN_CONDITION_PRESS, TEST_CONDITION_TEMP, TEST_CONDITION_PRESS, INSUL_CODE, PAINT_CODE, NDE_CODE, PWHT, PNID_NO) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" |
|
340 |
param = tuple(data) |
|
341 |
return (sql, tuple(param)) |
|
342 |
|
|
343 |
''' |
|
344 |
@brief return Line Data List |
|
345 |
@author kyouho |
|
346 |
@date 2018.08.14 |
|
347 |
''' |
|
348 |
def getLineDataList(self): |
|
349 |
dataList = [] |
|
350 |
try: |
|
351 |
import uuid |
|
352 |
global lineColumnList |
|
353 |
|
|
354 |
docData = AppDocData.instance() |
|
355 |
attrs = self.getAttributes() |
|
356 |
#attrs = attrs.items() |
|
357 |
for index in range(len(lineColumnList)): |
|
358 |
dataList.append('') |
|
359 |
|
|
360 |
dataList[20] = docData.imgName |
|
361 |
|
|
362 |
for key in attrs.keys(): |
|
363 |
if type(key) is not UserInputAttribute: |
|
364 |
lineProp = docData.getLinePropertiesByUID(key.UID) |
|
365 |
if lineProp: |
|
366 |
attrName = lineProp[0].Attribute.upper().replace(' ','') |
|
367 |
else: |
|
368 |
attrName = key.Attribute.upper().replace(' ','') |
|
369 |
|
|
370 |
data = attrs[key] |
|
371 |
if attrName == 'NOMINALDIAMETER': |
|
372 |
dataList[1] = data |
|
373 |
elif attrName == 'FLUIDCODE': |
|
374 |
dataList[2] = data |
|
375 |
dataList[7] = data |
|
376 |
elif attrName == 'TAGSEQNO': |
|
377 |
pass |
|
378 |
elif attrName == 'INSULATIONPURPOSE': |
|
379 |
dataList[16] = data |
|
380 |
elif attrName == 'STREAMNO': |
|
381 |
pass |
|
382 |
elif attrName == 'LINENO' or attrName == 'LINE NO': |
|
383 |
dataList[3] = data |
|
384 |
elif attrName == 'PNIDNUMBER': |
|
385 |
pass |
|
386 |
elif attrName == 'PIPINGMATERIALSCLASS': |
|
387 |
dataList[4] = data |
|
388 |
elif attrName == '': |
|
389 |
pass |
|
390 |
else: |
|
391 |
typeUID = key.Attribute |
|
392 |
value = key.text |
|
393 |
lineAttr = docData.getLinePropertiesByUID(key.UD) |
|
394 |
|
|
395 |
for index in range(len(lineColumnList)): |
|
396 |
if lineColumnList[index] == lineAttr[0].Attribute: |
|
397 |
dataList[index] = value |
|
398 |
except Exception as ex: |
|
399 |
from App import App |
|
400 |
from AppDocData import MessageType |
|
401 |
|
|
402 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
403 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
404 |
|
|
405 |
if dataList[0] == '': |
|
406 |
dataList[0] = str(uuid.uuid4()) |
|
407 |
|
|
408 |
return dataList |
HYTOS/HYTOS/Shapes/EngineeringNozzleItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
|
|
3 |
import sys |
|
4 |
import os |
|
5 |
import math |
|
6 |
from PyQt5.QtGui import * |
|
7 |
from PyQt5.QtCore import * |
|
8 |
from PyQt5.QtSvg import * |
|
9 |
from PyQt5.QtWidgets import (QApplication, QGraphicsItem) |
|
10 |
|
|
11 |
from SymbolSvgItem import SymbolSvgItem |
|
12 |
from EngineeringConnectorItem import QEngineeringConnectorItem |
|
13 |
|
|
14 |
class QEngineeringNozzleItem(SymbolSvgItem): |
|
15 |
ZVALUE = 20 |
|
16 |
clicked = pyqtSignal(QGraphicsSvgItem) |
|
17 |
|
|
18 |
''' |
|
19 |
''' |
|
20 |
def __init__(self, path, uid=None, flip=0): |
|
21 |
SymbolSvgItem.__init__(self, path, uid, flip=flip) |
|
22 |
|
|
23 |
self._props = [['Name', None], ['Size', None]] |
|
24 |
self.setZValue(QEngineeringNozzleItem.ZVALUE) |
|
25 |
|
|
26 |
''' |
|
27 |
@brief getter of property |
|
28 |
@author humkyung |
|
29 |
@date 2018.07.29 |
|
30 |
''' |
|
31 |
@property |
|
32 |
def props(self): |
|
33 |
return self._props |
|
34 |
|
|
35 |
''' |
|
36 |
@brief connect attribute |
|
37 |
@author humkyung |
|
38 |
@date 2018.07.19 |
|
39 |
''' |
|
40 |
def connectAttribute(self, attributes, clear=True): |
|
41 |
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem |
|
42 |
|
|
43 |
super(QEngineeringNozzleItem, self).connectAttribute(attributes, clear) |
|
44 |
|
|
45 |
rect = self.sceneBoundingRect() |
|
46 |
attrs = [attr for attr in attributes if type(attr) is QEngineeringTagNoTextItem] |
|
47 |
# check if text locates inside equipment |
|
48 |
for attr in attrs: |
|
49 |
if rect.contains(attr.center()): |
|
50 |
self.attrs.append(attr) |
|
51 |
attrs.remove(attr) |
|
52 |
break |
|
53 |
|
|
54 |
if not self.attrs: |
|
55 |
minDist = None |
|
56 |
selected = None |
|
57 |
# get nearest text from nozzle |
|
58 |
for attr in attrs: |
|
59 |
dx = attr.center().x() - rect.center().x() |
|
60 |
dy = attr.center().y() - rect.center().y() |
|
61 |
dist = math.sqrt(dx*dx + dy*dy) |
|
62 |
if (minDist is None) or (dist < minDist): |
|
63 |
minDist = dist |
|
64 |
selected = attr |
|
65 |
|
|
66 |
if selected is not None: |
|
67 |
self.attrs.append(selected) |
|
68 |
selected.onwer = self |
HYTOS/HYTOS/Shapes/EngineeringNozzleNameItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
|
|
3 |
import os.path |
|
4 |
import sys |
|
5 |
import copy |
|
6 |
try: |
|
7 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
8 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
9 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem |
|
10 |
except ImportError: |
|
11 |
try: |
|
12 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
13 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
14 |
except ImportError: |
|
15 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
16 |
|
|
17 |
from AppDocData import AppDocData |
|
18 |
from EngineeringTextItem import QEngineeringTextItem |
|
19 |
|
|
20 |
class QEngineeringNozzleNameItem(QEngineeringTextItem): |
|
21 |
|
|
22 |
''' |
|
23 |
''' |
|
24 |
def __init__(self, parent=None): |
|
25 |
QEngineeringTextItem.__init__(self, parent) |
|
26 |
|
|
27 |
self._runs = [] |
|
28 |
|
|
29 |
appDocData = AppDocData.instance() |
|
30 |
attributes = appDocData.getSymbolAttribute('Nozzle') |
|
31 |
self._attrs = [[attr, None] for attr in attributes] |
|
32 |
|
|
33 |
''' |
|
34 |
@brief getter of attributes |
|
35 |
@author humkyung |
|
36 |
@date 2018.07.29 |
|
37 |
''' |
|
38 |
@property |
|
39 |
def attrs(self): |
|
40 |
return self._attrs |
HYTOS/HYTOS/Shapes/EngineeringReservedWordTextItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is engineering reserved word text item module """ |
|
3 |
|
|
4 |
import os.path |
|
5 |
import sys |
|
6 |
import copy |
|
7 |
|
|
8 |
try: |
|
9 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
10 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
11 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, \ |
|
12 |
QGraphicsTextItem |
|
13 |
except ImportError: |
|
14 |
try: |
|
15 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
16 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
17 |
except ImportError: |
|
18 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
19 |
|
|
20 |
from AppDocData import AppDocData, MessageType |
|
21 |
from EngineeringTextItem import QEngineeringTextItem |
|
22 |
|
|
23 |
|
|
24 |
class QEngineeringReservedWordTextItem(QEngineeringTextItem): |
|
25 |
""" This is engineering reserved words text item class """ |
|
26 |
|
|
27 |
def __init__(self, uid=None, parent=None): |
|
28 |
QEngineeringTextItem.__init__(self, uid, parent) |
|
29 |
self.type = 'Reserved Word' |
HYTOS/HYTOS/Shapes/EngineeringRunItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is engineering run item moduel """ |
|
3 |
|
|
4 |
import sys |
|
5 |
import os.path |
|
6 |
import copy |
|
7 |
try: |
|
8 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QObject, QT_VERSION_STR |
|
9 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform |
|
10 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsPathItem |
|
11 |
except ImportError: |
|
12 |
try: |
|
13 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QObject, QT_VERSION_STR |
|
14 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog |
|
15 |
except ImportError: |
|
16 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
17 |
|
|
18 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
|
19 |
|
|
20 |
class QEngineeringRunItem(QEngineeringAbstractItem): |
|
21 |
""" This is engineering run item class """ |
|
22 |
|
|
23 |
def __init__(self): |
|
24 |
import uuid |
|
25 |
QEngineeringAbstractItem.__init__(self) |
|
26 |
|
|
27 |
self.uid = uuid.uuid4() # generate UUID |
|
28 |
self._items = [] |
|
29 |
self._visible = False |
|
30 |
self.owner = None |
|
31 |
|
|
32 |
@property |
|
33 |
def Type(self): |
|
34 |
""" return type of run(Drain/Process) """ |
|
35 |
from SymbolSvgItem import SymbolSvgItem |
|
36 |
from EngineeringLineItem import QEngineeringLineItem |
|
37 |
|
|
38 |
if len(self._items) == 2: |
|
39 |
if 1 == len([item for item in self._items if type(item) is QEngineeringLineItem]) and\ |
|
40 |
1 == len([item for item in self._items if type(item) is SymbolSvgItem]): return 'Drain' |
|
41 |
|
|
42 |
return 'Process' |
|
43 |
|
|
44 |
@property |
|
45 |
def visible(self): |
|
46 |
""" return visible """ |
|
47 |
return self._visible |
|
48 |
|
|
49 |
@visible.setter |
|
50 |
def visible(self, value): |
|
51 |
""" set visible value """ |
|
52 |
self._visible = value |
|
53 |
for item in self.items: |
|
54 |
if issubclass(type(item), QGraphicsItem): |
|
55 |
item.setVisible(value) |
|
56 |
|
|
57 |
''' |
|
58 |
@brief getter of items |
|
59 |
@author humkyung |
|
60 |
@date 2018.05.15 |
|
61 |
''' |
|
62 |
@property |
|
63 |
def items(self): |
|
64 |
return self._items |
|
65 |
|
|
66 |
''' |
|
67 |
@brief setter of items |
|
68 |
@author humkyung |
|
69 |
@date 2018.05.15 |
|
70 |
''' |
|
71 |
@items.setter |
|
72 |
def items(self, value): |
|
73 |
self._items = value |
|
74 |
|
|
75 |
def explode(self): |
|
76 |
""" explode run and subtract it from line no """ |
|
77 |
|
|
78 |
try: |
|
79 |
for item in self.items: |
|
80 |
item.owner = None |
|
81 |
finally: |
|
82 |
self.items.clear() |
|
83 |
|
|
84 |
if self.owner: self.owner.runs.remove(self) |
|
85 |
|
|
86 |
''' |
|
87 |
@brief get two points which's length is max |
|
88 |
@author humkyung |
|
89 |
@date 2018.05.23 |
|
90 |
''' |
|
91 |
def getLongestTwoPoints(self, pts): |
|
92 |
import math |
|
93 |
res = [None, None] |
|
94 |
|
|
95 |
maxDistance = None |
|
96 |
for i in range(len(pts)): |
|
97 |
for j in range(i+1, len(pts)): |
|
98 |
dx = pts[i][0] - pts[j][0] |
|
99 |
dy = pts[i][1] - pts[j][1] |
|
100 |
dist = math.sqrt(dx*dx + dy*dy) |
|
101 |
if (maxDistance is None) or (maxDistance < dist): |
|
102 |
maxDistance = dist |
|
103 |
res[0] = pts[i] |
|
104 |
res[1] = pts[j] |
|
105 |
|
|
106 |
return res |
|
107 |
|
|
108 |
def arrange_flow_direction(self): |
|
109 |
""" arrange flow direction of line """ |
|
110 |
from EngineeringLineItem import QEngineeringLineItem |
|
111 |
|
|
112 |
for at in range(len(self.items)): |
|
113 |
if type(self.items[at]) is QEngineeringLineItem and at > 0: |
|
114 |
self.items[at].arrange_flow_direction(self.items[at-1]) |
|
115 |
elif type(self.items[at]) is QEngineeringLineItem and len(self.items) > 1: |
|
116 |
self.items[at].arrange_flow_direction(self.items[at+1]) |
|
117 |
self.items[at].reverse() |
|
118 |
|
|
119 |
def reverse(self): |
|
120 |
""" reverse line's flow direction """ |
|
121 |
from EngineeringLineItem import QEngineeringLineItem |
|
122 |
|
|
123 |
self.items.reverse() |
|
124 |
for at in range(len(self.items)): |
|
125 |
if type(self.items[at]) is QEngineeringLineItem: |
|
126 |
self.items[at].reverse() |
|
127 |
|
|
128 |
''' |
|
129 |
@brief add flow mark |
|
130 |
@author humkyung |
|
131 |
@date 2018.06.17 |
|
132 |
''' |
|
133 |
def addFlowMark(self): |
|
134 |
from EngineeringLineItem import QEngineeringLineItem |
|
135 |
|
|
136 |
try: |
|
137 |
connectedLines = [item for item in self.items if type(item) is QEngineeringLineItem] |
|
138 |
|
|
139 |
maxLength = None |
|
140 |
maxLengthItem = None |
|
141 |
for line in connectedLines: |
|
142 |
length = line.length() |
|
143 |
if maxLength is None or maxLength < length: |
|
144 |
maxLength = length |
|
145 |
maxLengthItem = line |
|
146 |
|
|
147 |
if maxLengthItem is not None: maxLengthItem.addFlowArrow() |
|
148 |
except Exception as ex: |
|
149 |
from App import App |
|
150 |
from AppDocData import MessageType |
|
151 |
|
|
152 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
153 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
154 |
|
|
155 |
''' |
|
156 |
@brief write to xml |
|
157 |
@author humkyung |
|
158 |
@date 2018.05.16 |
|
159 |
@history Jeongwoo 2018.05.24 Add math.fabs() on sublist's if-statement |
|
160 |
Change toler(1 → 5) and Modify Longest Line's coords // Make comments Test Code |
|
161 |
humkyung 2018.06.22 sort lines before writing to xml |
|
162 |
kyouho 2018.08.09 Line 묶기 |
|
163 |
''' |
|
164 |
def toXml(self): |
|
165 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
|
166 |
from EngineeringLineItem import QEngineeringLineItem |
|
167 |
from SymbolSvgItem import SymbolSvgItem |
|
168 |
|
|
169 |
try: |
|
170 |
node = Element('RUN') |
|
171 |
node.attrib['TYPE'] = self.Type |
|
172 |
for item in self.items: |
|
173 |
# skip line item which's connected items are same |
|
174 |
if (type(item) is QEngineeringLineItem) and item.connectors[0].connectedItem is not None and (item.connectors[0].connectedItem is item.connectors[1].connectedItem): |
|
175 |
continue |
|
176 |
# up to here |
|
177 |
|
|
178 |
node.append(item.toXml()) |
|
179 |
|
|
180 |
except Exception as ex: |
|
181 |
from App import App |
|
182 |
from AppDocData import MessageType |
|
183 |
|
|
184 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
185 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
186 |
return None |
|
187 |
|
|
188 |
return node |
HYTOS/HYTOS/Shapes/QEngineeringSizeTextItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
import os.path |
|
3 |
import sys |
|
4 |
import copy |
|
5 |
try: |
|
6 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
7 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
8 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem |
|
9 |
except ImportError: |
|
10 |
try: |
|
11 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
12 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
13 |
except ImportError: |
|
14 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
15 |
|
|
16 |
from EngineeringPolylineItem import QEngineeringPolylineItem |
|
17 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
|
18 |
from AppDocData import AppDocData, MessageType |
|
19 |
from EngineeringTextItem import QEngineeringTextItem |
|
20 |
from SymbolSvgItem import SymbolSvgItem |
|
21 |
|
|
22 |
class QEngineeringSizeTextItem(QEngineeringTextItem): |
|
23 |
|
|
24 |
def __init__(self, parent=None): |
|
25 |
import uuid |
|
26 |
|
|
27 |
QEngineeringTextItem.__init__(self, parent) |
|
28 |
self.type = 'SIZE' |
|
29 |
|
|
30 |
def findOwner(self, symbols): |
|
31 |
import math |
|
32 |
|
|
33 |
try: |
|
34 |
minDist = None |
|
35 |
selected = None |
|
36 |
|
|
37 |
configs = AppDocData.instance().getConfigs('Size', 'Delimiter') |
|
38 |
delimiter = configs[0].value.upper() if configs else 'X' |
|
39 |
configs = AppDocData.instance().getConfigs('Range', 'Detection Ratio') |
|
40 |
ratio = float(configs[0].value) if 1 == len(configs) else 1.5 |
|
41 |
|
|
42 |
dist = (self.sceneBoundingRect().height() + self.sceneBoundingRect().width()) * ratio / 2 |
|
43 |
center = self.sceneBoundingRect().center() |
|
44 |
|
|
45 |
for symbol in symbols: |
|
46 |
if delimiter in self.text().upper() and type(symbol) is QEngineeringReducerItem: |
|
47 |
dx = symbol.center().x() - center.x() |
|
48 |
dy = symbol.center().y() - center.y() |
|
49 |
length = math.sqrt(dx*dx + dy*dy) |
|
50 |
if (length < dist) and (minDist is None or length < minDist): |
|
51 |
minDist = length |
|
52 |
selected = symbol |
|
53 |
|
|
54 |
elif not delimiter in self.text().upper() and type(symbol) is SymbolSvgItem: |
|
55 |
dx = symbol.center().x() - center.x() |
|
56 |
dy = symbol.center().y() - center.y() |
|
57 |
length = math.sqrt(dx*dx + dy*dy) |
|
58 |
if (length < dist) and (minDist is None or length < minDist): |
|
59 |
minDist = length |
|
60 |
selected = symbol |
|
61 |
|
|
62 |
if selected is not None: |
|
63 |
if selected.add_assoc_item(self): |
|
64 |
self.owner = selected |
|
65 |
|
|
66 |
except Exception as ex: |
|
67 |
from App import App |
|
68 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
69 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
HYTOS/HYTOS/Shapes/QEngineeringTagNoTextItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is engineering tag no text item module """ |
|
3 |
|
|
4 |
import os.path |
|
5 |
import sys |
|
6 |
import copy |
|
7 |
|
|
8 |
try: |
|
9 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
10 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
11 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, \ |
|
12 |
QGraphicsTextItem |
|
13 |
except ImportError: |
|
14 |
try: |
|
15 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
16 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
17 |
except ImportError: |
|
18 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
19 |
|
|
20 |
from AppDocData import AppDocData, MessageType |
|
21 |
from EngineeringTextItem import QEngineeringTextItem |
|
22 |
|
|
23 |
|
|
24 |
class QEngineeringTagNoTextItem(QEngineeringTextItem): |
|
25 |
""" This is engineering tag no text item class """ |
|
26 |
|
|
27 |
def __init__(self, parent=None): |
|
28 |
import uuid |
|
29 |
|
|
30 |
QEngineeringTextItem.__init__(self, parent) |
|
31 |
self.type = 'TAG NO' |
|
32 |
|
|
33 |
def findOwner(self, symbols): |
|
34 |
import math |
|
35 |
|
|
36 |
try: |
|
37 |
minDist = None |
|
38 |
selected = None |
|
39 |
|
|
40 |
configs = AppDocData.instance().getConfigs('Range', 'Detection Ratio') |
|
41 |
ratio = float(configs[0].value) if 1 == len(configs) else 1.5 |
|
42 |
|
|
43 |
dist = (self.sceneBoundingRect().height() + self.sceneBoundingRect().width()) * ratio |
|
44 |
center = self.sceneBoundingRect().center() |
|
45 |
|
|
46 |
for symbol in symbols: |
|
47 |
if type(symbol) is QEngineeringEquipmentItem: |
|
48 |
if symbol.includes([self.sceneBoundingRect().center().x(), self.sceneBoundingRect().center().y()]): |
|
49 |
selected = symbol |
|
50 |
break |
|
51 |
|
|
52 |
if selected is None: |
|
53 |
for symbol in symbols: |
|
54 |
if type(symbol) is QEngineeringEquipmentItem: |
|
55 |
dx = symbol.center().x() - center.x() |
|
56 |
dy = symbol.center().y() - center.y() |
|
57 |
length = math.sqrt(dx * dx + dy * dy) |
|
58 |
if (length < dist) and (minDist is None or length < minDist): |
|
59 |
minDist = length |
|
60 |
selected = symbol |
|
61 |
|
|
62 |
if selected is not None: |
|
63 |
if selected.add_assoc_item(self): |
|
64 |
self.owner = selected |
|
65 |
|
|
66 |
except Exception as ex: |
|
67 |
from App import App |
|
68 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
69 |
sys.exc_info()[-1].tb_lineno) |
|
70 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
HYTOS/HYTOS/Shapes/SymbolSvgItem.py | ||
---|---|---|
187 | 187 |
try: |
188 | 188 |
rect = self.boundingRect() |
189 | 189 |
if rect.isValid(): |
190 |
#self.resetTransform() |
|
191 |
#self.setPos(change.topLeft()) |
|
192 | 190 |
scale = max(min([change.width() / rect.width(), change.height() / rect.height()]), 1) |
193 | 191 |
# scale the item |
194 | 192 |
self.setScale(scale) |
... | ... | |
1296 | 1294 |
self.setColor('url(#normal)') |
1297 | 1295 |
self.update() |
1298 | 1296 |
|
1299 |
''' |
|
1300 |
@brief change cursor to CrossCursor if mouse point is close to connection point |
|
1301 |
@author humkyung |
|
1302 |
@date 2018.04.28 |
|
1303 |
''' |
|
1304 |
|
|
1305 |
def hoverMoveEvent(self, event): |
|
1306 |
pass |
|
1307 |
|
|
1308 | 1297 |
def mousePressEvent(self, event): |
1309 | 1298 |
import math |
1310 | 1299 |
|
1311 | 1300 |
if event.buttons() == Qt.LeftButton: |
1312 |
toler = 10
|
|
1301 |
toler = 5*self.scale()
|
|
1313 | 1302 |
|
1314 | 1303 |
# try to select corner |
1315 |
self._selected_idx = None |
|
1316 | 1304 |
pos = event.scenePos() |
1317 |
for idx, corner in enumerate(self.corners): |
|
1318 |
dx = corner.x() - pos.x() |
|
1319 |
dy = corner.y() - pos.y() |
|
1320 |
if math.sqrt(dx * dx + dy * dy) < toler: |
|
1321 |
self._selected_idx = idx |
|
1322 |
break |
|
1305 |
corner = self.corners[2] |
|
1306 |
dx = corner.x() - pos.x() |
|
1307 |
dy = corner.y() - pos.y() |
|
1308 |
self._selected_idx = 2 if math.sqrt(dx * dx + dy * dy) < toler else None |
|
1323 | 1309 |
# up to here |
1324 | 1310 |
|
1325 |
if self._selected_idx is None: |
|
1326 |
self.clicked.emit(self) |
|
1327 |
|
|
1328 |
#super(SymbolSvgItem, self).mousePressEvent(event) |
|
1311 |
super(SymbolSvgItem, self).mousePressEvent(event) |
|
1329 | 1312 |
|
1330 | 1313 |
def mouseMoveEvent(self, event): |
1331 | 1314 |
"""reshape dimension""" |
... | ... | |
1922 | 1905 |
''' |
1923 | 1906 |
|
1924 | 1907 |
def draw_focus_rect(self, painter): |
1925 |
self.focuspen = QPen(Qt.DotLine) |
|
1926 |
self.focuspen.setColor(Qt.black) |
|
1927 |
self.focuspen.setWidthF(1.5) |
|
1928 | 1908 |
hilightColor = QColor(255, 0, 0, 127) |
1929 | 1909 |
painter.setBrush(QBrush(hilightColor)) |
1930 |
painter.setPen(self.focuspen) |
|
1931 |
painter.drawRect(self.boundingRect()) |
|
1910 |
|
|
1911 |
corner = self.corners[2] |
|
1912 |
pt = self.mapFromScene(corner) |
|
1913 |
painter.drawEllipse(pt, 5, 5) |
|
1932 | 1914 |
|
1933 | 1915 |
def paint(self, painter, options=None, widget=None): |
1934 | 1916 |
"""override paint(draw connection points)""" |
1935 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
|
1936 |
from EngineeringTextItem import QEngineeringTextItem |
|
1937 |
|
|
1938 | 1917 |
self.setColor(self.getColor()) |
1939 | 1918 |
|
1940 | 1919 |
painter.setClipRect(options.exposedRect) |
1941 | 1920 |
QGraphicsSvgItem.paint(self, painter, options, widget) |
1942 |
""" |
|
1943 |
for attr in self.attrs: |
|
1944 |
if issubclass(type(attr), QEngineeringTextItem): |
|
1945 |
color = QEngineeringAbstractItem.HOVER_COLOR if self.hover else ( |
|
1946 |
self._owner._color if self._owner else QEngineeringAbstractItem.DEFAULT_COLOR) |
|
1947 |
attr.setColor(color) |
|
1948 |
elif issubclass(type(attr), SymbolSvgItem): |
|
1949 |
attr.setColor(self.getColor()) |
|
1950 |
attr.update() |
|
1951 |
""" |
|
1952 | 1921 |
|
1953 | 1922 |
if self.isSelected(): |
1954 | 1923 |
self.draw_focus_rect(painter) |
내보내기 Unified diff