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