hytos / HYTOS / HYTOS / Shapes / EngineeringPolylineItem.py @ ce5ca212
이력 | 보기 | 이력해설 | 다운로드 (7.77 KB)
1 |
# coding: utf-8
|
---|---|
2 |
"""
|
3 |
This is Polyline item module
|
4 |
"""
|
5 |
|
6 |
import sys |
7 |
import os.path |
8 |
import copy |
9 |
try:
|
10 |
from PyQt5.QtCore import Qt, QRectF, pyqtSignal, QObject, QT_VERSION_STR |
11 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QPolygonF, QColor, QTransform |
12 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsPathItem |
13 |
except ImportError: |
14 |
try:
|
15 |
from PyQt4.QtCore import Qt, QRectF, QObject, pyqtSignal, QT_VERSION_STR |
16 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QColor |
17 |
except ImportError: |
18 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
19 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
20 |
|
21 |
class QEngineeringPolylineItem(QGraphicsPathItem, QEngineeringAbstractItem): |
22 |
"""
|
23 |
This is EngineeringPolylineItem Class
|
24 |
"""
|
25 |
|
26 |
AXIS_MODE = 0
|
27 |
FREE_MODE = 1
|
28 |
|
29 |
onRemoved = pyqtSignal(QGraphicsItem) |
30 |
|
31 |
'''
|
32 |
@history 2018.05.11 Jeongwoo Declare variable self.pen
|
33 |
2018.05.15 Jeongwoo Change method to call parent's __init__
|
34 |
2018.05.25 Jeongwoo Change self.pen's default color (red → blue)
|
35 |
'''
|
36 |
def __init__(self, uid=None, parent=None): |
37 |
import uuid |
38 |
|
39 |
try:
|
40 |
QGraphicsPathItem.__init__(self, parent)
|
41 |
QEngineeringAbstractItem.__init__(self)
|
42 |
self.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable)
|
43 |
|
44 |
self.uid = uuid.uuid4() if uid is None else uid |
45 |
self._vertices = []
|
46 |
self.isCreated = False |
47 |
self._pt = None |
48 |
self._pol = QPolygonF()
|
49 |
self._path = None |
50 |
self.setPen(QPen(Qt.blue, 4, Qt.SolidLine)) # set default pen |
51 |
|
52 |
self.transfer = Transfer()
|
53 |
|
54 |
self._drawing_mode = QEngineeringPolylineItem.AXIS_MODE
|
55 |
|
56 |
except Exception as ex: |
57 |
from App import App |
58 |
from AppDocData import MessageType |
59 |
|
60 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
61 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
62 |
|
63 |
@property
|
64 |
def drawing_mode(self): |
65 |
return self._drawing_mode |
66 |
|
67 |
@drawing_mode.setter
|
68 |
def drawing_mode(self, value): |
69 |
self._drawing_mode = value
|
70 |
|
71 |
'''
|
72 |
@brief construct a polyline
|
73 |
'''
|
74 |
def process(self, param): |
75 |
if ('mousePressEvent' == param[0]) and (param[1].button() == Qt.LeftButton): |
76 |
self._vertices.append(param[2]) |
77 |
elif ('mouseMoveEvent' == param[0]): |
78 |
self._pt = param[2] |
79 |
elif ('mouseReleaseEvent' == param[0]) and (param[1].button() == Qt.RightButton): |
80 |
self.isCreated = True |
81 |
|
82 |
'''
|
83 |
@brief clone an object
|
84 |
'''
|
85 |
def clone(self): |
86 |
clone = QEngineeringPolylineItem() |
87 |
clone._vertices = copy.deepcopy(self._vertices)
|
88 |
clone.isCreated = self.isCreated
|
89 |
|
90 |
return clone
|
91 |
|
92 |
def init(self): |
93 |
self._vertices = []
|
94 |
self._pol.clear()
|
95 |
self._pt = None |
96 |
self.isCreated = False |
97 |
|
98 |
'''
|
99 |
@build build path
|
100 |
@author humkyung
|
101 |
@date 2018.04.23
|
102 |
'''
|
103 |
def buildItem(self): |
104 |
self._path = QPainterPath()
|
105 |
self._path.addPolygon(self._pol) |
106 |
self.setPath(self._path) |
107 |
self.isCreated = True |
108 |
|
109 |
'''
|
110 |
@brief return bouding rectangle of polyline
|
111 |
@author humkyung
|
112 |
@date 2018.07.23
|
113 |
'''
|
114 |
def boundingRect(self): |
115 |
rect = QRectF() |
116 |
|
117 |
if self.isCreated: |
118 |
rect = self.path().boundingRect()
|
119 |
rect = QRectF(rect.left() - 5, rect.top() - 5, rect.width() + 10, rect.height() + 10) |
120 |
else:
|
121 |
minX = None
|
122 |
minY = None
|
123 |
maxX = None
|
124 |
maxY = None
|
125 |
for pt in self._vertices: |
126 |
if minX is None or pt[0] < minX: |
127 |
minX = pt[0]
|
128 |
if minY is None or pt[1] < minY: |
129 |
minY = pt[1]
|
130 |
|
131 |
if maxX is None or pt[0] > maxX: |
132 |
maxX = pt[0]
|
133 |
if maxY is None or pt[1] > maxY: |
134 |
maxY = pt[1]
|
135 |
|
136 |
if self._pt is not None: |
137 |
if minX is None or self._pt[0] < minX: |
138 |
minX = self._pt[0] |
139 |
if minY is None or self._pt[1] < minY: |
140 |
minY = self._pt[1] |
141 |
|
142 |
if maxX is None or self._pt[0] > maxX: |
143 |
maxX = self._pt[0] |
144 |
if maxY is None or self._pt[1] > maxY: |
145 |
maxY = self._pt[1] |
146 |
|
147 |
if minX is not None and minY is not None and maxX is not None and maxY is not None: |
148 |
rect = QRectF(minX - 5, minY - 5, maxX - minX + 10, maxY - minY + 10) |
149 |
|
150 |
return rect
|
151 |
|
152 |
'''
|
153 |
@brief
|
154 |
@author humkyung
|
155 |
@date 2018.07.26
|
156 |
'''
|
157 |
def onMouseMoved(self, event, scenePos): |
158 |
from SymbolSvgItem import SymbolSvgItem |
159 |
from EngineeringConnectorItem import QEngineeringConnectorItem |
160 |
|
161 |
# get connection point near by mouse point
|
162 |
pt = (scenePos.x(), scenePos.y()) |
163 |
item = self.scene().itemAt(scenePos, QTransform())
|
164 |
if (item is not None) and (type(item) is SymbolSvgItem): |
165 |
connPt = item.getConnectionPointCloseTo(pt, 5)
|
166 |
if connPt is not None: pt = connPt |
167 |
elif (item is not None) and (type(item) is QEngineeringConnectorItem): |
168 |
pt = item.center() |
169 |
# up to here
|
170 |
|
171 |
if self.drawing_mode == QEngineeringPolylineItem.AXIS_MODE and len(self._vertices) > 0: |
172 |
dx = abs(self._vertices[-1][0] - pt[0]) |
173 |
dy = abs(self._vertices[-1][1] - pt[1]) |
174 |
if dx < dy:
|
175 |
self._pt = (self._vertices[-1][0], pt[1]) |
176 |
else:
|
177 |
self._pt = (pt[0], self._vertices[-1][1]) |
178 |
else:
|
179 |
self._pt = pt
|
180 |
|
181 |
self.update()
|
182 |
|
183 |
'''
|
184 |
@brief Return real item position
|
185 |
@authro Jeongwoo
|
186 |
@date 2018.05.29
|
187 |
'''
|
188 |
def boundingRectOnScene(self): |
189 |
rect = self.boundingRect()
|
190 |
sp = self.startPoint()
|
191 |
rect.moveTo(sp[0], sp[1]) |
192 |
return rect
|
193 |
|
194 |
'''
|
195 |
@brief paint
|
196 |
@history 2018.05.11 Jeongwoo Change variable pen → self.pen
|
197 |
'''
|
198 |
def paint(self, painter, options=None, widget=None): |
199 |
if self.isCreated: |
200 |
painter.setPen(self.pen())
|
201 |
QGraphicsPathItem.paint(self, painter, options, widget)
|
202 |
elif len(self._vertices) > 0: |
203 |
painter.setPen(self.pen())
|
204 |
for i in range(len(self._vertices)-1): |
205 |
painter.drawLine(self._vertices[i][0], self._vertices[i][1], self._vertices[i+1][0], self._vertices[i+1][1]) |
206 |
if self._pt is not None: |
207 |
painter.drawLine(self._vertices[-1][0], self._vertices[-1][1], self._pt[0], self._pt[1]) |
208 |
|
209 |
'''
|
210 |
@brief Set Color. Override QEngineeringAbstractItem's
|
211 |
@author Jeongwoo
|
212 |
@date 2018.05.11
|
213 |
@history 2018.05.11 Jeongwoo Add self.setPen() Method
|
214 |
@history humkyung 2018.05.13 call setPen method to apply changed color
|
215 |
'''
|
216 |
def setColor(self, color): |
217 |
c = QColor() |
218 |
c.setNamedColor(color) |
219 |
_pen = self.pen()
|
220 |
_pen.setColor(c) |
221 |
self.setPen(_pen)
|
222 |
self.update()
|
223 |
|
224 |
'''
|
225 |
@brief The class transfer pyqtSignal Event. Cause Subclass of QGraphicsRectItem can't use pyqtSignal
|
226 |
@author Jeongwoo
|
227 |
@date 2018.06.18
|
228 |
'''
|
229 |
class Transfer(QObject): |
230 |
onRemoved = pyqtSignal(QGraphicsItem) |
231 |
|
232 |
def __init__(self, parent = None): |
233 |
QObject.__init__(self, parent)
|