개정판 c8ef167e
issue #1062:
1. Stream line 삭제 시 연결 정보가 해제되지 않는 현상 수정
2. 연결점 이동하는 기능 개선
Change-Id: I712d501b1679a640c79c2fbe8c2933f1627ac323
HYTOS/HYTOS/Commands/AreaZoomCommand.py | ||
---|---|---|
1 | 1 |
import os.path |
2 | 2 |
import AbstractCommand |
3 |
|
|
3 | 4 |
try: |
4 | 5 |
from PyQt5.QtCore import * |
5 | 6 |
from PyQt5.QtGui import * |
... | ... | |
11 | 12 |
except ImportError: |
12 | 13 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
13 | 14 |
|
15 |
|
|
14 | 16 |
class AreaZoomCommand(AbstractCommand.AbstractCommand): |
15 | 17 |
onRejected = pyqtSignal(AbstractCommand.AbstractCommand) |
16 | 18 |
|
17 | 19 |
''' |
18 | 20 |
@history 2018.06.27 Jeongwoo Add variables [startPoint, endPoint] |
19 | 21 |
''' |
22 |
|
|
20 | 23 |
def __init__(self, imageViewer): |
21 | 24 |
super(AreaZoomCommand, self).__init__(imageViewer) |
22 |
self.name = 'AreaZoom'
|
|
25 |
self.name = 'AreaZoom' |
|
23 | 26 |
self.imageViewer.setCursor(QCursor(Qt.CrossCursor)) |
24 | 27 |
|
25 | 28 |
self._rubberBand = QRubberBand(QRubberBand.Rectangle, self.imageViewer) |
26 | 29 |
self._origin = QPoint() |
27 | 30 |
self.isLeftClicked = False |
28 |
|
|
31 |
|
|
29 | 32 |
''' |
30 | 33 |
@brief pan image by left click and drag |
31 | 34 |
@history 2018.06.27 Jeongwoo Add if-statement for panning after zoom in / Add variable [startPoint, endPoint] |
32 | 35 |
humkyung 2018.08.29 use rubberband to select area |
33 | 36 |
''' |
37 |
|
|
34 | 38 |
def execute(self, param): |
35 | 39 |
event = param[1] |
36 | 40 |
scenePos = param[2] |
37 |
|
|
41 |
|
|
38 | 42 |
self.isTreated = False |
39 | 43 |
if 'mousePressEvent' == param[0]: |
40 | 44 |
if event.button() == Qt.LeftButton: |
... | ... | |
43 | 47 |
self._origin = event.pos() |
44 | 48 |
self._rubberBand.setGeometry(QRect(self._origin, QSize())) |
45 | 49 |
self._rubberBand.show() |
46 |
|
|
50 |
|
|
47 | 51 |
self.imageViewer.leftMouseButtonPressed.emit(scenePos.x(), scenePos.y()) |
48 | 52 |
elif 'mouseMoveEvent' == param[0] and event.buttons() == Qt.LeftButton: |
49 | 53 |
if self._rubberBand.isVisible(): |
... | ... | |
56 | 60 |
self._rubberBand.hide() |
57 | 61 |
topLeft = self.imageViewer.mapToScene(self._rubberBand.geometry().topLeft()) |
58 | 62 |
bottomRight = self.imageViewer.mapToScene(self._rubberBand.geometry().bottomRight()) |
59 |
self.imageViewer.zoomStack.append(QRectF(topLeft.x(), topLeft.y(), bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())) |
|
63 |
self.imageViewer.zoomStack.append( |
|
64 |
QRectF(topLeft.x(), topLeft.y(), bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())) |
|
60 | 65 |
self.imageViewer.updateViewer() |
61 | 66 |
elif event.button() == Qt.RightButton: |
62 |
if self.isLeftClicked == False:
|
|
67 |
if not self.isLeftClicked:
|
|
63 | 68 |
self.onRejected.emit(self) |
64 | 69 |
finally: |
65 | 70 |
pass |
... | ... | |
84 | 89 |
scenePos2 = self.imageViewer.mapToScene(pos.x() + 300, pos.y() + 300) |
85 | 90 |
if isZoomIn: |
86 | 91 |
zoomArea = QRectF(QPointF(scenePos1.x(), scenePos1.y()), QPointF(scenePos2.x(), scenePos2.y())) |
87 |
viewBBox = self.imageViewer.zoomStack[-1] if len(self.imageViewer.zoomStack) else self.imageViewer.sceneRect() |
|
92 |
viewBBox = self.imageViewer.zoomStack[-1] if len( |
|
93 |
self.imageViewer.zoomStack) else self.imageViewer.sceneRect() |
|
88 | 94 |
selectionBBox = zoomArea.intersected(viewBBox) |
89 | 95 |
self.imageViewer.scene.setSelectionArea(QPainterPath()) # Clear current selection area. |
90 | 96 |
if selectionBBox.isValid() and (selectionBBox != viewBBox): |
... | ... | |
94 | 100 |
self.imageViewer.scene.setSelectionArea(QPainterPath()) # Clear current selection area. |
95 | 101 |
if len(self.imageViewer.zoomStack): |
96 | 102 |
self.imageViewer.zoomStack.pop() |
97 |
self.imageViewer.updateViewer() |
|
103 |
self.imageViewer.updateViewer() |
HYTOS/HYTOS/Commands/ZoomCommand.py | ||
---|---|---|
1 | 1 |
import os.path |
2 | 2 |
import AbstractCommand |
3 |
|
|
3 | 4 |
try: |
4 | 5 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR |
5 | 6 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QCursor |
... | ... | |
11 | 12 |
except ImportError: |
12 | 13 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
13 | 14 |
|
15 |
|
|
14 | 16 |
class ZoomCommand(AbstractCommand.AbstractCommand): |
15 | 17 |
def __init__(self, imageViewer): |
16 | 18 |
super(ZoomCommand, self).__init__(imageViewer) |
17 |
self.name = 'Zoom'
|
|
19 |
self.name = 'Zoom' |
|
18 | 20 |
self.imageViewer.setCursor(QCursor(Qt.PointingHandCursor)) |
19 |
|
|
21 |
|
|
20 | 22 |
''' |
21 | 23 |
@brief pan image by left click and drag |
22 | 24 |
''' |
25 |
|
|
23 | 26 |
def execute(self, param): |
24 | 27 |
event = param[1] |
25 | 28 |
if 'mousePressEvent' == param[0]: |
26 | 29 |
if self.imageViewer.canZoom: |
27 |
if (event.button() == Qt.RightButton):
|
|
30 |
if event.button() == Qt.RightButton:
|
|
28 | 31 |
self.zoomImage(False, event.pos()) |
29 | 32 |
else: |
30 | 33 |
self.zoomImage(True, event.pos()) |
... | ... | |
54 | 57 |
scenePos1 = self.imageViewer.mapToScene(pos.x() - 300, pos.y() - 300) |
55 | 58 |
scenePos2 = self.imageViewer.mapToScene(pos.x() + 300, pos.y() + 300) |
56 | 59 |
if isZoomIn: |
57 |
#print("zoom in") |
|
60 |
# print("zoom in")
|
|
58 | 61 |
zoomArea = QRectF(QPointF(scenePos1.x(), scenePos1.y()), QPointF(scenePos2.x(), scenePos2.y())) |
59 |
viewBBox = self.imageViewer.zoomStack[-1] if len(self.imageViewer.zoomStack) else self.imageViewer.sceneRect() |
|
62 |
viewBBox = self.imageViewer.zoomStack[-1] if \ |
|
63 |
len(self.imageViewer.zoomStack) else self.imageViewer.sceneRect() |
|
60 | 64 |
selectionBBox = zoomArea.intersected(viewBBox) |
61 | 65 |
self.imageViewer.scene.setSelectionArea(QPainterPath()) # Clear current selection area. |
62 | 66 |
if selectionBBox.isValid() and (selectionBBox != viewBBox): |
63 | 67 |
self.imageViewer.zoomStack.append(selectionBBox) |
64 | 68 |
self.imageViewer.updateViewer() |
65 | 69 |
else: |
66 |
#print("zoom out") |
|
70 |
# print("zoom out")
|
|
67 | 71 |
self.imageViewer.scene.setSelectionArea(QPainterPath()) # Clear current selection area. |
68 | 72 |
if len(self.imageViewer.zoomStack): |
69 | 73 |
self.imageViewer.zoomStack.pop() |
70 |
self.imageViewer.updateViewer() |
|
74 |
self.imageViewer.updateViewer() |
HYTOS/HYTOS/MainWindow.py | ||
---|---|---|
135 | 135 |
self.actionOptions.triggered.connect(self.onOptions) |
136 | 136 |
self.actionZoom.triggered.connect(self.onAreaZoom) |
137 | 137 |
self.actionFitWindow.triggered.connect(self.fitWindow) |
138 |
self.actionViewConnector.triggered.connect(self.on_view_connector) |
|
138 | 139 |
self.actionSymbol_Editor.triggered.connect(self.showSymbolEditor) |
139 | 140 |
self.actionHelp.triggered.connect(self.on_help) |
140 | 141 |
self.actionAbout.triggered.connect(self.on_about) |
... | ... | |
301 | 302 |
|
302 | 303 |
def eventFilter(self, source, event): |
303 | 304 |
""" display mouse position of graphics view """ |
304 |
if (event.type() == QEvent.MouseMove):
|
|
305 |
if event.type() == QEvent.MouseMove:
|
|
305 | 306 |
pos = self.graphicsView.mapToScene(event.pos()) |
306 | 307 |
self._label_mouse.setText('mouse pos : ({},{})'.format(round(pos.x()), round(pos.y()))) |
307 | 308 |
|
308 | 309 |
return QWidget.eventFilter(self, source, event) |
309 | 310 |
|
310 | 311 |
def load_stylesheet(self, file): |
311 |
""" |
|
312 |
@brief load stylesheets |
|
313 |
@author humkyung |
|
314 |
@date 2018.10.29 |
|
315 |
""" |
|
312 |
"""load stylesheets""" |
|
316 | 313 |
|
317 | 314 |
QtWidgets.qApp.loadStyleSheet(os.path.join(os.path.dirname(os.path.realpath(__file__)), file)) |
318 | 315 |
|
... | ... | |
325 | 322 |
action.setChecked(False) |
326 | 323 |
|
327 | 324 |
def load_language(self, file): |
328 |
""" |
|
329 |
load language file and then apply selected language |
|
330 |
""" |
|
325 |
""" load language file and then apply selected language """ |
|
331 | 326 |
try: |
332 | 327 |
|
333 | 328 |
qm_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'translate', '{0}.qm'.format(file)) |
... | ... | |
721 | 716 |
self.graphicsView.useDefaultCommand() |
722 | 717 |
self.graphicsView.zoomImageInit() |
723 | 718 |
|
719 |
def on_view_connector(self, action): |
|
720 |
"""turn on/off connector""" |
|
721 |
for item in self.graphicsView.scene.items(): |
|
722 |
if not hasattr(item, 'connectors'): |
|
723 |
continue |
|
724 |
for connector in item.connectors: |
|
725 |
connector.setVisible(True) if action else connector.hide() |
|
726 |
|
|
724 | 727 |
def scene_changed(self): |
725 | 728 |
"""update modified flag""" |
726 | 729 |
|
... | ... | |
955 | 958 |
if image_path: |
956 | 959 |
self.graphicsView.save_as_image(image_path) |
957 | 960 |
|
958 |
workspace = self.getWorkSpace()
|
|
961 |
workspace = self.get_work_space()
|
|
959 | 962 |
file_name = os.path.join(workspace, app_doc_data.activeDrawing.name + '.xlsx') |
960 | 963 |
options = QFileDialog.Options() |
961 | 964 |
options |= QFileDialog.DontUseNativeDialog |
... | ... | |
1931 | 1934 |
from datetime import datetime |
1932 | 1935 |
from Drawing import Drawing |
1933 | 1936 |
|
1934 |
workspace = self.getWorkSpace()
|
|
1937 |
workspace = self.get_work_space()
|
|
1935 | 1938 |
|
1936 | 1939 |
options = QFileDialog.Options() |
1937 | 1940 |
options |= QFileDialog.DontUseNativeDialog |
... | ... | |
1971 | 1974 |
|
1972 | 1975 |
self.save_drawing_if_necessary() |
1973 | 1976 |
|
1974 |
workspace = self.getWorkSpace()
|
|
1977 |
workspace = self.get_work_space()
|
|
1975 | 1978 |
|
1976 | 1979 |
options = QFileDialog.Options() |
1977 | 1980 |
options |= QFileDialog.DontUseNativeDialog |
... | ... | |
1998 | 2001 |
self.load_data(drawing) |
1999 | 2002 |
|
2000 | 2003 |
def on_open_drawing(self): |
2001 |
""" open selected drawing by user """
|
|
2004 |
"""open selected drawing by user"""
|
|
2002 | 2005 |
|
2003 | 2006 |
self.save_drawing_if_necessary() |
2004 | 2007 |
|
2005 |
workspace = self.getWorkSpace()
|
|
2008 |
workspace = self.get_work_space()
|
|
2006 | 2009 |
options = QFileDialog.Options() |
2007 | 2010 |
options |= QFileDialog.DontUseNativeDialog |
2008 | 2011 |
name, _ = QFileDialog.getOpenFileName(self, self.tr('Open'), workspace, 'HYTOS File(*.hytos)', options=options) |
... | ... | |
2010 | 2013 |
self.open_drawing(name) |
2011 | 2014 |
|
2012 | 2015 |
def open_drawing(self, name): |
2013 |
""" open given drawing has name """
|
|
2016 |
"""open given drawing has name"""
|
|
2014 | 2017 |
import uuid |
2015 | 2018 |
from Drawing import Drawing |
2016 | 2019 |
from datetime import datetime |
... | ... | |
2036 | 2039 |
# connect scene changed signal |
2037 | 2040 |
self.graphicsView.scene.contents_changed.connect(self.scene_changed) |
2038 | 2041 |
|
2039 |
def getWorkSpace(self):
|
|
2040 |
""" get work space path """
|
|
2042 |
def get_work_space(self):
|
|
2043 |
"""get work space path"""
|
|
2041 | 2044 |
app_doc_data = AppDocData.instance() |
2042 | 2045 |
|
2043 | 2046 |
configs = app_doc_data.getAppConfigs('option', 'WorkSpace') |
... | ... | |
2047 | 2050 |
return os.getcwd() |
2048 | 2051 |
|
2049 | 2052 |
def changeViewCheckedState(self, checked, clear=True): |
2050 |
''' |
|
2051 |
@brief change view checked state |
|
2052 |
@author euisung |
|
2053 |
@date 2019.03.06 |
|
2054 |
''' |
|
2053 |
'''change view checked state''' |
|
2055 | 2054 |
if clear: |
2056 | 2055 |
self.initTableWidgetHMB() |
2057 | 2056 |
# self.clear_data() |
... | ... | |
2305 | 2304 |
sys.exc_info()[-1].tb_lineno) |
2306 | 2305 |
self.addMessage.emit(MessageType.Error, message) |
2307 | 2306 |
|
2308 |
''' |
|
2309 |
@brief remove item from tree widget and then remove from scene |
|
2310 |
@date 2018.05.25 |
|
2311 |
@author Jeongwoo |
|
2312 |
''' |
|
2313 |
|
|
2314 | 2307 |
def on_item_removed(self, item): |
2308 |
"""remove item from tree widget and then remove from scene""" |
|
2309 |
|
|
2315 | 2310 |
try: |
2316 | 2311 |
matches = [_item for _item in self.graphicsView.scene.items() if hasattr(_item, 'connectors') and \ |
2317 | 2312 |
[connector for connector in _item.connectors if |
2318 | 2313 |
connector.connectedItem is not None and connector.connectedItem.parentItem() is item]] |
2314 |
# disconnect deleted item |
|
2319 | 2315 |
for match in matches: |
2320 | 2316 |
for connector in match.connectors: |
2321 |
if connector.connectedItem is item: connector.connect(None) |
|
2317 |
if connector.connectedItem and connector.connectedItem.parentItem() is item: |
|
2318 |
connector.connect(None) |
|
2322 | 2319 |
|
2323 | 2320 |
matches = [_item for _item in self.graphicsView.scene.items() if hasattr(_item, 'owner')] |
2324 | 2321 |
for match in matches: |
... | ... | |
2347 | 2344 |
item.scene().removeItem(item) |
2348 | 2345 |
del item |
2349 | 2346 |
except Exception as ex: |
2350 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
2347 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
2351 | 2348 |
sys.exc_info()[-1].tb_lineno) |
2352 | 2349 |
self.addMessage.emit(MessageType.Error, message) |
2353 | 2350 |
|
HYTOS/HYTOS/MainWindow_UI.py | ||
---|---|---|
268 | 268 |
font.setFamily("맑은 고딕") |
269 | 269 |
self.actionSave.setFont(font) |
270 | 270 |
self.actionSave.setObjectName("actionSave") |
271 |
self.actionRotate = QtWidgets.QAction(MainWindow) |
|
271 |
self.actionViewConnector = QtWidgets.QAction(MainWindow) |
|
272 |
self.actionViewConnector.setCheckable(True) |
|
272 | 273 |
icon11 = QtGui.QIcon() |
273 | 274 |
icon11.addPixmap(QtGui.QPixmap(":/newPrefix/Rotate_Minus.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) |
274 |
self.actionRotate.setIcon(icon11)
|
|
275 |
self.actionRotate.setObjectName("actionRotate")
|
|
275 |
self.actionViewConnector.setIcon(icon11)
|
|
276 |
self.actionViewConnector.setObjectName("actionViewConnector")
|
|
276 | 277 |
self.actioncoffee = QtWidgets.QAction(MainWindow) |
277 | 278 |
self.actioncoffee.setObjectName("actioncoffee") |
278 | 279 |
self.actionEnglish = QtWidgets.QAction(MainWindow) |
... | ... | |
366 | 367 |
self.menu.addAction(self.actionClose) |
367 | 368 |
self.menu_3.addAction(self.actionZoom) |
368 | 369 |
self.menu_3.addAction(self.actionFitWindow) |
370 |
self.menu_3.addSeparator() |
|
371 |
self.menu_3.addAction(self.actionViewConnector) |
|
369 | 372 |
self.menuTool.addAction(self.actionLine) |
370 | 373 |
self.menuTool.addAction(self.actionInitialize) |
371 | 374 |
self.menuTool.addSeparator() |
... | ... | |
421 | 424 |
self.actionSave.setText(_translate("MainWindow", "Save")) |
422 | 425 |
self.actionSave.setToolTip(_translate("MainWindow", "Save")) |
423 | 426 |
self.actionSave.setShortcut(_translate("MainWindow", "Ctrl+S")) |
424 |
self.actionRotate.setText(_translate("MainWindow", "Rotate"))
|
|
425 |
self.actionRotate.setToolTip(_translate("MainWindow", "Rotate(Ctrl + R)"))
|
|
426 |
self.actionRotate.setShortcut(_translate("MainWindow", "Ctrl+R"))
|
|
427 |
self.actionViewConnector.setText(_translate("MainWindow", "View Connector"))
|
|
428 |
self.actionViewConnector.setToolTip(_translate("MainWindow", "View Connector(Alt + C)"))
|
|
429 |
self.actionViewConnector.setShortcut(_translate("MainWindow", "Alt+C"))
|
|
427 | 430 |
self.actioncoffee.setText(_translate("MainWindow", "coffee")) |
428 | 431 |
self.actionEnglish.setText(_translate("MainWindow", "English")) |
429 | 432 |
self.actionViewInconsistency.setText(_translate("MainWindow", "Inconsistency (6)")) |
HYTOS/HYTOS/Shapes/EngineeringAbstractItem.py | ||
---|---|---|
23 | 23 |
self._hover = False |
24 | 24 |
self._area = None |
25 | 25 |
self.connectors = [] |
26 |
self.attrs = {} # attributes |
|
26 |
self.attrs = {} # attributes
|
|
27 | 27 |
self._associations = {'Text Item':[], 'Symbol Item':[]} # associated items |
28 | 28 |
|
29 | 29 |
@property |
HYTOS/HYTOS/Shapes/EngineeringConnectorItem.py | ||
---|---|---|
3 | 3 |
|
4 | 4 |
import os.path |
5 | 5 |
import copy, sys |
6 |
|
|
6 | 7 |
try: |
7 | 8 |
from PyQt5.QtCore import * |
8 | 9 |
from PyQt5.QtGui import * |
... | ... | |
16 | 17 |
|
17 | 18 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
18 | 19 |
|
20 |
|
|
19 | 21 |
class NozzleData: |
20 | 22 |
""" this is nozzle data class """ |
21 | 23 |
|
... | ... | |
42 | 44 |
from App import App |
43 | 45 |
from AppDocData import MessageType |
44 | 46 |
|
45 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
47 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
48 |
sys.exc_info()[-1].tb_lineno) |
|
46 | 49 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
47 | 50 |
|
51 |
|
|
48 | 52 |
""" |
49 | 53 |
A {ConnectorItem} is the graphical representation of a {Symbol.Connectors}. |
50 | 54 |
""" |
55 |
|
|
56 |
|
|
51 | 57 |
class QEngineeringConnectorItem(QGraphicsEllipseItem): |
52 | 58 |
""" This is engineering connector item class """ |
53 | 59 |
SMALL_SIZE = 10 |
... | ... | |
64 | 70 |
@history humkyung 2018.07.27 add member for connectedItem |
65 | 71 |
humkyung 2018.09.03 remove code to add connector item |
66 | 72 |
''' |
73 |
|
|
67 | 74 |
def __init__(self, uid=None, parent=None, index=-1): |
68 | 75 |
import uuid |
69 | 76 |
from SymbolSvgItem import SymbolSvgItem |
... | ... | |
76 | 83 |
self._direction = 'AUTO' |
77 | 84 |
self._symbol_idx = '0' |
78 | 85 |
self._connectedItem = None |
79 |
self._connected_at = QEngineeringAbstractItem.CONNECTED_AT_PT # default value is connected at pt
|
|
86 |
self._connected_at = QEngineeringAbstractItem.CONNECTED_AT_PT # default value is connected at pt |
|
80 | 87 |
self.connectPoint = None |
81 | 88 |
self._hoverItem = None |
82 | 89 |
self._data = None |
... | ... | |
100 | 107 |
@staticmethod |
101 | 108 |
def find_connector(uid): |
102 | 109 |
""" find a connector which has given uid """ |
103 |
from App import App
|
|
110 |
from App import App |
|
104 | 111 |
import uuid |
105 | 112 |
|
106 | 113 |
res = None |
... | ... | |
143 | 150 |
self._connectedItem = None |
144 | 151 |
|
145 | 152 |
return self._connectedItem |
146 |
|
|
153 |
|
|
147 | 154 |
@connectedItem.setter |
148 | 155 |
def connectedItem(self, value): |
149 | 156 |
""" setter of connectedItem """ |
... | ... | |
154 | 161 |
@author humkyung |
155 | 162 |
@date 2018.09.01 |
156 | 163 |
''' |
164 |
|
|
157 | 165 |
@property |
158 | 166 |
def direction(self): |
159 | 167 |
return self._direction |
... | ... | |
163 | 171 |
@author humkyung |
164 | 172 |
@date 2018.09.01 |
165 | 173 |
''' |
174 |
|
|
166 | 175 |
@direction.setter |
167 | 176 |
def direction(self, value): |
168 | 177 |
self._direction = value |
169 |
|
|
178 |
|
|
170 | 179 |
@property |
171 | 180 |
def symbol_idx(self): |
172 | 181 |
""" """ |
... | ... | |
187 | 196 |
@author humkyung |
188 | 197 |
@date 2018.09.01 |
189 | 198 |
''' |
199 |
|
|
190 | 200 |
def dir(self): |
191 | 201 |
if self._direction == 'LEFT': |
192 | 202 |
return (-1, 0) |
... | ... | |
204 | 214 |
@author humkyung |
205 | 215 |
@date 2018.05.02 |
206 | 216 |
''' |
217 |
|
|
207 | 218 |
def buildItem(self): |
208 | 219 |
color = Qt.blue |
209 | 220 |
self.setBrush(color) |
... | ... | |
215 | 226 |
@author humkyung |
216 | 227 |
@date 2018.07.23 |
217 | 228 |
''' |
229 |
|
|
218 | 230 |
def center(self): |
219 | 231 |
pt = self.sceneBoundingRect().center() |
220 | 232 |
return (pt.x(), pt.y()) |
221 |
|
|
233 |
|
|
222 | 234 |
''' |
223 | 235 |
@brief set position of connector |
224 | 236 |
@author humkyung |
225 | 237 |
@date 2018.05.02 |
226 | 238 |
''' |
239 |
|
|
227 | 240 |
def setPos(self, pos): |
228 |
self._loc = [pos[0], pos[1]] |
|
229 |
self.setRect(self._loc[0] - round(self.SMALL_SIZE*0.5), self._loc[1] - round(self.SMALL_SIZE*0.5), self.SMALL_SIZE, self.SMALL_SIZE) |
|
241 |
self._loc = [pos[0], pos[1]] |
|
242 |
self.setRect(self._loc[0] - round(self.SMALL_SIZE * 0.5), self._loc[1] - round(self.SMALL_SIZE * 0.5), |
|
243 |
self.SMALL_SIZE, self.SMALL_SIZE) |
|
230 | 244 |
self.update() |
231 | 245 |
|
232 | 246 |
if hasattr(self, '_label'): |
233 | 247 |
""" set label positon at center of connector """ |
234 |
self._label.setPos(QPointF(self._loc[0] - self._label.boundingRect().width()*0.5, self._loc[1] - self._label.boundingRect().height()*0.5)) |
|
235 |
|
|
248 |
self._label.setPos(QPointF(self._loc[0] - self._label.boundingRect().width() * 0.5, |
|
249 |
self._loc[1] - self._label.boundingRect().height() * 0.5)) |
|
250 |
|
|
236 | 251 |
def connect(self, item, at=QEngineeringAbstractItem.CONNECTED_AT_PT): |
237 |
""" connect to given item where given position """
|
|
252 |
"""connect to given item where given position"""
|
|
238 | 253 |
|
239 | 254 |
if item: |
240 | 255 |
self.connectedItem = item |
... | ... | |
244 | 259 |
|
245 | 260 |
self.setBrush(Qt.yellow) if self.connectedItem else self.setBrush(Qt.blue) |
246 | 261 |
|
247 |
''' |
|
248 |
@brief highlight connector |
|
249 |
@authro humkyung |
|
250 |
@date 2018.05.09 |
|
251 |
''' |
|
252 | 262 |
def hoverEnterEvent(self, event): |
263 |
"""highlight connector""" |
|
264 |
from EngineeringStreamlineItem import QEngineeringStreamlineItem |
|
265 |
|
|
253 | 266 |
try: |
254 |
self.highlight(True) |
|
267 |
if type(self.parentItem()) is not QEngineeringStreamlineItem: |
|
268 |
items = self.scene().items(event.scenePos()) |
|
269 |
matched = [item for item in items if type(item.parentItem()) is QEngineeringStreamlineItem] |
|
270 |
if matched: |
|
271 |
matched[0].hoverEnterEvent(event) |
|
272 |
else: |
|
273 |
self.highlight(True) |
|
274 |
else: |
|
275 |
self.highlight(True) |
|
255 | 276 |
finally: |
256 | 277 |
QApplication.setOverrideCursor(Qt.CrossCursor) |
257 | 278 |
|
258 |
''' |
|
259 |
@brief unhighlight connector |
|
260 |
@author humkyung |
|
261 |
@date 2018.05.09 |
|
262 |
''' |
|
263 | 279 |
def hoverLeaveEvent(self, event): |
280 |
"""unhighlight connector""" |
|
264 | 281 |
try: |
265 | 282 |
self.highlight(False) |
266 | 283 |
finally: |
267 | 284 |
QApplication.restoreOverrideCursor() |
268 | 285 |
|
269 | 286 |
def highlight(self, flag): |
287 |
"""highlight or unhighlight""" |
|
288 |
|
|
270 | 289 |
if flag: |
271 |
self.setRect(self._loc[0] - round(self.BIG_SIZE*0.5), self._loc[1] - round(self.BIG_SIZE*0.5), self.BIG_SIZE, self.BIG_SIZE) |
|
290 |
self.setRect(self._loc[0] - round(self.BIG_SIZE * 0.5), self._loc[1] - round(self.BIG_SIZE * 0.5), |
|
291 |
self.BIG_SIZE, self.BIG_SIZE) |
|
272 | 292 |
c = QColor() |
273 | 293 |
c.setNamedColor(QEngineeringConnectorItem.HIGHLIGHT) |
274 | 294 |
self.setPen(Qt.red) |
... | ... | |
277 | 297 |
font = self._label.font() |
278 | 298 |
font.setBold(True) |
279 | 299 |
self._label.setFont(font) |
300 |
self.parentItem().highlight(flag) |
|
280 | 301 |
else: |
281 |
self.setRect(self._loc[0] - round(self.SMALL_SIZE*0.5), self._loc[1] - round(self.SMALL_SIZE*0.5), self.SMALL_SIZE, self.SMALL_SIZE) |
|
302 |
self.setRect(self._loc[0] - round(self.SMALL_SIZE * 0.5), self._loc[1] - round(self.SMALL_SIZE * 0.5), |
|
303 |
self.SMALL_SIZE, self.SMALL_SIZE) |
|
282 | 304 |
self.setPen(Qt.black) |
283 | 305 |
self.setBrush(Qt.yellow) if self.connectedItem else self.setBrush(Qt.blue) |
284 | 306 |
if hasattr(self, '_label'): |
... | ... | |
286 | 308 |
font.setBold(False) |
287 | 309 |
self._label.setFont(font) |
288 | 310 |
|
289 |
if self.parentItem(): self.setZValue(self.parentItem().zValue() + 1) |
|
311 |
self.parentItem().highlight(flag) |
|
312 |
|
|
290 | 313 |
if self.scene() and self.scene().sceneRect().contains(self.sceneBoundingRect()): |
291 | 314 |
self.update() |
292 | 315 |
if self.scene(): self.scene().update() |
... | ... | |
296 | 319 |
@author humkyung |
297 | 320 |
@date 2018.07.27 |
298 | 321 |
''' |
322 |
|
|
299 | 323 |
def mousePressEvent(self, event): |
300 | 324 |
if self.parentItem() is not None: |
301 | 325 |
if event.buttons() == Qt.LeftButton: |
302 | 326 |
self._savedPos = self._loc |
303 | 327 |
self._savedConnectedItem = self.connectedItem |
304 |
|
|
328 |
|
|
305 | 329 |
QGraphicsEllipseItem.mousePressEvent(self, event) |
306 | 330 |
|
307 | 331 |
''' |
... | ... | |
310 | 334 |
@date 2018.07.27 |
311 | 335 |
@history humkyung 2018.08.23 unhighlight item if underitem exists |
312 | 336 |
''' |
337 |
|
|
313 | 338 |
def mouseReleaseEvent(self, event): |
314 | 339 |
import shapely |
315 | 340 |
from SymbolSvgItem import SymbolSvgItem |
316 | 341 |
from EngineeringArrowItem import QEngineeringArrowItem |
317 | 342 |
from EngineeringTextItem import QEngineeringTextItem |
318 | 343 |
|
319 |
try:
|
|
344 |
try: |
|
320 | 345 |
if self.parentItem() is not None and self._savedPos is not None: |
321 |
items = [item for item in self.scene().items(event.scenePos()) if item is not self and item is not self.parentItem() and \ |
|
322 |
(issubclass(type(item), SymbolSvgItem) or issubclass(type(item), QEngineeringTextItem) or type(item) is QEngineeringConnectorItem)] |
|
346 |
items = [item for item in self.scene().items(event.scenePos()) if |
|
347 |
item is not self and item is not self.parentItem() and \ |
|
348 |
(issubclass(type(item), SymbolSvgItem) or issubclass(type(item), QEngineeringTextItem) or type( |
|
349 |
item) is QEngineeringConnectorItem)] |
|
323 | 350 |
|
324 | 351 |
if items and type(items[0]) is QEngineeringConnectorItem: |
325 | 352 |
self.setPos(items[0].center()) |
326 |
|
|
327 |
""" disconnect alreay connected item """ |
|
353 |
|
|
354 |
""" disconnect already connected item """
|
|
328 | 355 |
if self.connectedItem is not None: |
329 | 356 |
self.connectedItem.connect(None) |
330 | 357 |
|
... | ... | |
333 | 360 |
items[0].connect(self) |
334 | 361 |
else: |
335 | 362 |
pt = [event.scenePos().x(), event.scenePos().y()] |
336 |
|
|
363 |
|
|
337 | 364 |
self.setPos(pt) |
338 | 365 |
if self.connectedItem is not None: |
339 | 366 |
self.connectedItem.connect(None) |
... | ... | |
349 | 376 |
symbol.transfer.on_pos_changed.connect(self.parent.on_symbol_pos_changed) |
350 | 377 |
|
351 | 378 |
if self.parentItem() is not None: |
352 |
self._savedPos = None
|
|
379 |
self._savedPos = None |
|
353 | 380 |
self._savedConnectedItem = None |
354 |
self.transfer.onPosChanged.emit(self)
|
|
381 |
self.transfer.onPosChanged.emit(self) |
|
355 | 382 |
finally: |
356 |
#self.ungrabKeyboard() |
|
357 | 383 |
pass |
358 | 384 |
|
359 | 385 |
QGraphicsEllipseItem.mouseReleaseEvent(self, event) |
... | ... | |
364 | 390 |
@date 2018.07.27 |
365 | 391 |
@history humkyung 2018.08.23 hightlight underitem |
366 | 392 |
''' |
393 |
|
|
367 | 394 |
def mouseMoveEvent(self, event): |
368 | 395 |
import shapely |
369 | 396 |
from SymbolSvgItem import SymbolSvgItem |
... | ... | |
372 | 399 |
|
373 | 400 |
if self.parentItem() is not None and self._savedPos is not None: |
374 | 401 |
if event.buttons() == Qt.LeftButton: |
375 |
items = [item for item in self.scene().items(event.scenePos()) if item is not self and item is not self.parent and \ |
|
376 |
(issubclass(type(item), SymbolSvgItem) or issubclass(type(item), QEngineeringTextItem) or type(item) is QEngineeringConnectorItem)] |
|
402 |
items = [item for item in self.scene().items(event.scenePos()) if |
|
403 |
item is not self and item is not self.parent and \ |
|
404 |
(issubclass(type(item), SymbolSvgItem) or issubclass(type(item), QEngineeringTextItem) or type( |
|
405 |
item) is QEngineeringConnectorItem)] |
|
377 | 406 |
## highlight underitem |
378 | 407 |
if len(items) > 0: |
379 | 408 |
if not hasattr(self, '_underItem') or self._underItem is not items[0]: |
... | ... | |
391 | 420 |
self.setPos(items[0].center()) |
392 | 421 |
else: |
393 | 422 |
pt = [event.scenePos().x(), event.scenePos().y()] |
394 |
|
|
423 |
|
|
395 | 424 |
self.setPos(pt) |
396 | 425 |
|
397 | 426 |
self.update() |
398 | 427 |
|
399 | 428 |
QGraphicsEllipseItem.mouseMoveEvent(self, event) |
400 | 429 |
|
401 |
|
|
402 | 430 |
def hasConnectedItem(self): |
403 | 431 |
if self.connectedItem is not None: |
404 | 432 |
return True |
405 |
|
|
433 |
|
|
406 | 434 |
return False |
435 |
|
|
407 | 436 |
''' |
408 | 437 |
@brief reject if user press Escape key |
409 | 438 |
@author humkyung |
410 | 439 |
@date 2018.07.27 |
411 | 440 |
''' |
441 |
|
|
412 | 442 |
def keyPressEvent(self, event): |
413 | 443 |
if event.key() == Qt.Key_Escape: |
414 | 444 |
if hasattr(self, '_savedPos') and self._savedPos is not None: |
... | ... | |
428 | 458 |
@author humkyung |
429 | 459 |
@date 2018.04.21 |
430 | 460 |
''' |
461 |
|
|
431 | 462 |
def paint(self, painter, options=None, widget=None): |
432 | 463 |
from SymbolSvgItem import SymbolSvgItem |
433 | 464 |
|
... | ... | |
441 | 472 |
@author kyouho |
442 | 473 |
@date 2018.08.30 |
443 | 474 |
''' |
444 |
def isOverlapConnector(self, conn, toler = 10): |
|
475 |
|
|
476 |
def isOverlapConnector(self, conn, toler=10): |
|
445 | 477 |
from shapely.geometry import Point |
446 | 478 |
|
447 | 479 |
x1 = self.center()[0] |
... | ... | |
462 | 494 |
if 'UID' in node.attrib: self.uid = uuid.UUID(node.attrib['UID'], version=4) |
463 | 495 |
|
464 | 496 |
if 'CONNECTED_AT' in node.attrib: |
465 |
self._connected_at = QEngineeringAbstractItem.CONNECTED_AT_PT if node.attrib['CONNECTED_AT'] == '0' else QEngineeringAbstractItem.CONNECTED_AT_BODY |
|
497 |
self._connected_at = QEngineeringAbstractItem.CONNECTED_AT_PT if node.attrib[ |
|
498 |
'CONNECTED_AT'] == '0' else QEngineeringAbstractItem.CONNECTED_AT_BODY |
|
466 | 499 |
else: |
467 | 500 |
self._connected_at = QEngineeringAbstractItem.CONNECTED_AT_PT |
468 | 501 |
|
... | ... | |
476 | 509 |
|
477 | 510 |
self.setBrush(Qt.yellow) if self._connectedItem else self.setBrush(Qt.blue) |
478 | 511 |
except Exception as ex: |
479 |
from App import App
|
|
512 |
from App import App |
|
480 | 513 |
from AppDocData import MessageType |
481 | 514 |
|
482 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
515 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
516 |
sys.exc_info()[-1].tb_lineno) |
|
483 | 517 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
484 | 518 |
|
485 | 519 |
def toSql(self, index): |
... | ... | |
522 | 556 |
else: |
523 | 557 |
over_design_cv = float(over_design_cv) |
524 | 558 |
|
525 |
|
|
526 | 559 |
param = [str(self.uid), pressure, pressure_drop, elevation, over_design_cv] |
527 | 560 |
sql = 'insert or replace into Nozzles({}) values({})'.format(','.join(cols), ','.join(values)) |
528 | 561 |
res.append((sql, tuple(param))) |
... | ... | |
532 | 565 |
from AppDocData import MessageType |
533 | 566 |
|
534 | 567 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
535 |
sys.exc_info()[-1].tb_lineno) |
|
568 |
sys.exc_info()[-1].tb_lineno)
|
|
536 | 569 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
537 | 570 |
|
538 | 571 |
return res |
539 | 572 |
|
573 |
|
|
540 | 574 |
''' |
541 | 575 |
@brief The class transfer pyqtSignal Event. Cause Subclass of QGraphicsRectItem can't use pyqtSignal |
542 | 576 |
@author Jeongwoo |
543 | 577 |
@date 2018.06.18 |
544 | 578 |
''' |
579 |
|
|
580 |
|
|
545 | 581 |
class Transfer(QObject): |
546 | 582 |
onPosChanged = pyqtSignal(QGraphicsItem) |
547 | 583 |
onRemoved = pyqtSignal(QGraphicsItem) |
548 | 584 |
|
549 |
def __init__(self, parent = None):
|
|
585 |
def __init__(self, parent=None):
|
|
550 | 586 |
QObject.__init__(self, parent) |
HYTOS/HYTOS/Shapes/EngineeringStreamlineItem.py | ||
---|---|---|
164 | 164 |
connector = QEngineeringConnectorItem(uid=None, parent=self, index=index + 1) |
165 | 165 |
|
166 | 166 |
connector.setPos(vertex) |
167 |
connector.setParentItem(self) |
|
168 | 167 |
connector.connectPoint = vertex |
169 | 168 |
connector.sceneConnectPoint = vertex |
170 | 169 |
|
HYTOS/HYTOS/Shapes/SymbolSvgItem.py | ||
---|---|---|
49 | 49 |
|
50 | 50 |
|
51 | 51 |
class SymbolSvgItem(QGraphicsSvgItem, QEngineeringAbstractItem): |
52 |
""" This is symbolsvgitem class """
|
|
52 |
"""This is SymbolSvgItem class"""
|
|
53 | 53 |
|
54 | 54 |
clicked = pyqtSignal(QGraphicsSvgItem) |
55 | 55 |
ZVALUE = 100 |
... | ... | |
123 | 123 |
self.setZValue(SymbolSvgItem.ZVALUE) |
124 | 124 |
self._desc_label = QEngineeringEqpDescTextItem('eqp name<br>pressure drop<br>elevation', self) |
125 | 125 |
|
126 |
# font = QFont('Arial') |
|
127 |
# font.setPointSizeF(6) |
|
128 |
# self._desc_label.setFont(font) |
|
129 |
|
|
130 |
# self._desc_label.setDefaultTextColor(Qt.red) |
|
131 |
|
|
132 |
# self._desc_label.setFont(6) |
|
133 |
|
|
134 | 126 |
def has_attribute(self): |
135 | 127 |
if len(self.attribute) > 0: |
136 | 128 |
return True |
HYTOS/HYTOS/UI/MainWindow.ui | ||
---|---|---|
321 | 321 |
</property> |
322 | 322 |
<addaction name="actionZoom"/> |
323 | 323 |
<addaction name="actionFitWindow"/> |
324 |
<addaction name="separator"/> |
|
325 |
<addaction name="actionViewConnector"/> |
|
324 | 326 |
</widget> |
325 | 327 |
<widget class="QMenu" name="menuTool"> |
326 | 328 |
<property name="title"> |
... | ... | |
538 | 540 |
<string>Ctrl+S</string> |
539 | 541 |
</property> |
540 | 542 |
</action> |
541 |
<action name="actionRotate"> |
|
543 |
<action name="actionViewConnector"> |
|
544 |
<property name="checkable"> |
|
545 |
<bool>true</bool> |
|
546 |
</property> |
|
542 | 547 |
<property name="icon"> |
543 | 548 |
<iconset> |
544 | 549 |
<normaloff>:/newPrefix/Rotate_Minus.png</normaloff>:/newPrefix/Rotate_Minus.png</iconset> |
545 | 550 |
</property> |
546 | 551 |
<property name="text"> |
547 |
<string>Rotate</string>
|
|
552 |
<string>View Connector</string>
|
|
548 | 553 |
</property> |
549 | 554 |
<property name="toolTip"> |
550 |
<string>Rotate(Ctrl + R)</string>
|
|
555 |
<string>View Connector(Alt + C)</string>
|
|
551 | 556 |
</property> |
552 | 557 |
<property name="shortcut"> |
553 |
<string>Ctrl+R</string>
|
|
558 |
<string>Alt+C</string>
|
|
554 | 559 |
</property> |
555 | 560 |
</action> |
556 | 561 |
<action name="actioncoffee"> |
내보내기 Unified diff