프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / HYTOS / HYTOS / Shapes / EngineeringStreamlineItem.py @ e69a3fd8

이력 | 보기 | 이력해설 | 다운로드 (46.7 KB)

1
# coding: utf-8
2
""" This is stream line item module """
3

    
4
import sys
5
import os.path
6
import copy
7
import numpy as np
8

    
9
try:
10
    from PyQt5.QtCore import *
11
    from PyQt5.QtGui import *
12
    from PyQt5.QtWidgets import *
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

    
22
class QEngineeringStreamlineItem(QGraphicsPathItem, QEngineeringAbstractItem):
23
    """ This is EngineeringStreamlineItem Class """
24

    
25
    ARROW_SIZE = 5
26
    ZVALUE = 50
27
    OFFSET = 10
28
    onRemoved = pyqtSignal(QGraphicsItem)
29

    
30
    '''
31
        @history    2018.05.11  Jeongwoo    Declare variable self.pen
32
                    2018.05.15  Jeongwoo    Change method to call parent's __init__
33
                    2018.05.25  Jeongwoo    Change self.pen's default color (red → blue)
34
    '''
35

    
36
    def __init__(self, uid=None, parent=None):
37
        import uuid
38
        from EngineeringStreamNoTextItem import QEngineeringStreamNoTextItem
39

    
40
        try:
41
            QGraphicsPathItem.__init__(self, parent)
42
            QEngineeringAbstractItem.__init__(self)
43
            self.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable)
44
            self.setAcceptHoverEvents(True)
45
            self.setAcceptTouchEvents(True)
46

    
47
            self.uid = uuid.uuid4() if uid is None else uid
48
            self.parent = parent
49
            self._vertices = []
50
            self.isCreated = False
51
            self._pt = None
52
            self.setPen(QPen(Qt.blue, 1, Qt.SolidLine)) # set default pen
53
            
54
            self._stream_no = 0
55
            self._stream_no_text = None
56

    
57
            self._fittings = None
58

    
59
            self.transfer = Transfer()
60
            self.setZValue(QEngineeringStreamlineItem.ZVALUE)
61
        except Exception as ex:
62
            from App import App
63
            from AppDocData import MessageType
64
            
65
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
66
                                                           sys.exc_info()[-1].tb_lineno)
67
            App.mainWnd().addMessage.emit(MessageType.Error, message)
68

    
69
    def __repr__(self):
70
        """ return string represents stream line item """
71
        return 'Line_{}'.format(self._stream_no)
72

    
73
    @property
74
    def fittings(self):
75
        """ return fittings """
76
        return self._fittings
77

    
78
    @fittings.setter
79
    def fittings(self, value):
80
        """ set fittings with given value """
81
        self._fittings = value
82

    
83

    
84
    @property
85
    def stream_no(self):
86
        """ return stream no """
87
        return self._stream_no
88

    
89
    @stream_no.setter
90
    def stream_no(self, value):
91
        """ set stream no with given value """
92
        from EngineeringStreamNoTextItem import QEngineeringStreamNoTextItem
93

    
94
        self._stream_no = value
95
        self._stream_no_text = QEngineeringStreamNoTextItem(f"{self._stream_no}", self)
96
        self.build_path()
97
        
98
    @property
99
    def data(self):
100
        """ return hmb data"""
101
        from AppDocData import AppDocData
102

    
103
        app_doc_data = AppDocData.instance()
104
        return app_doc_data.activeDrawing.hmbTable.get_hmb_data(self.uid)
105

    
106
    @property
107
    def density(self):
108
        """ return density """
109
        from AppDocData import AppDocData
110

    
111
        res = 0
112
        app_doc_data = AppDocData.instance()
113
        hmb_data = app_doc_data.activeDrawing.hmbTable.get_hmb_data(self.uid)
114
        if hmb_data: res = hmb_data.density
115

    
116
        return res
117

    
118
    @property
119
    def press_drop(self):
120
        """ return press drop """
121
        from AppDocData import AppDocData
122

    
123
        app_doc_data = AppDocData.instance()
124
        hmb_data = app_doc_data.activeDrawing.hmbTable.get_hmb_data(self.uid)
125

    
126
        return hmb_data.pressure_drop if hmb_data else 0
127

    
128
    def build_connectors(self, connected, pointsUids=None):
129
        """ build connectors for stream line
130
            connected is target connector
131
        """
132

    
133
        from SymbolSvgItem import SymbolSvgItem
134
        from EngineeringConnectorItem import QEngineeringConnectorItem 
135

    
136
        if not self._vertices:
137
            return
138

    
139
        targets = []
140
        index = 0
141
        for vertex in [self._vertices[0], self._vertices[-1]]:
142
            if pointsUids:
143
                connector = QEngineeringConnectorItem(pointsUids[index], parent=self, index=index+1)
144
            else: 
145
                connector = QEngineeringConnectorItem(uid=None, parent=self, index=index+1)
146

    
147
            connector.setPos(vertex)
148
            connector.setParentItem(self)
149
            connector.connectPoint = vertex
150
            connector.sceneConnectPoint = vertex
151

    
152
            # add connector move ables
153
            connector.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable)
154
            connector.setAcceptTouchEvents(True)
155
            connector.transfer.onPosChanged.connect(self.on_connector_pos_changed)
156

    
157
            connector.setZValue(self.zValue() + 1)
158
            self.connectors.append(connector)
159
            if len(connected) > index:
160
                connected_item_uid = connected[index]
161
                if connected_item_uid:
162
                    target = QEngineeringConnectorItem.find_connector(connected_item_uid)
163
                    connector.connect(target)
164
                    if target:
165
                        target.connect(connector)
166
                        targets.append(target)
167

    
168
            index = index + 1
169

    
170
        """ connect symbol's on_pos_changed signal """
171
        for symbol in [conn.parentItem() for conn in targets if type(conn.parentItem()) is SymbolSvgItem]:
172
            symbol.transfer.on_pos_changed.connect(self.on_symbol_pos_changed)
173
            symbol.transfer.on_size_changed.connect(self.on_symbol_pos_changed)
174

    
175
    def update_arrow(self):
176
        """ update flow arrow """
177
        import math
178
        from EngineeringArrowItem import QEngineeringArrowItem
179
        if len(self._vertices) < 2: return
180

    
181
        start = self._vertices[-2]
182
        end = self._vertices[-1]
183

    
184
        dx = end[0] - start[0]
185
        dy = end[1] - start[1]
186
        length = math.sqrt(dx*dx + dy*dy)
187
        if length == 0: return
188

    
189
        _dir = [(end[0] - start[0])/length, (end[1] - start[1])/length]
190
        perpendicular = (-_dir[1], _dir[0])
191
        polygon = QPolygonF()
192
        polygon.append(QPointF(end[0] - _dir[0] * QEngineeringStreamlineItem.ARROW_SIZE + perpendicular[
193
            0] * QEngineeringStreamlineItem.ARROW_SIZE * 0.25,
194
                               end[1] - _dir[1] * QEngineeringStreamlineItem.ARROW_SIZE + perpendicular[
195
                                   1] * QEngineeringStreamlineItem.ARROW_SIZE * 0.25))
196
        polygon.append(QPointF(end[0] - _dir[0] * QEngineeringStreamlineItem.ARROW_SIZE - perpendicular[
197
            0] * QEngineeringStreamlineItem.ARROW_SIZE * 0.25,
198
                               end[1] - _dir[1] * QEngineeringStreamlineItem.ARROW_SIZE - perpendicular[
199
                                   1] * QEngineeringStreamlineItem.ARROW_SIZE * 0.25))
200
        polygon.append(QPointF(end[0], end[1]))
201
        polygon.append(polygon[0])  # close polygon
202

    
203
        if not hasattr(self, '_arrow'):
204
            self._arrow = QEngineeringArrowItem(polygon, self)
205
        else:
206
            self._arrow.setPolygon(polygon)
207

    
208
        self._arrow.setPen(Qt.blue)
209
        self._arrow.setBrush(Qt.blue)
210
        self._arrow.update()
211

    
212
    '''
213
        @brief  construct a polyline
214
    '''
215

    
216
    def process(self, param):
217
        if ('mousePressEvent' == param[0]) and (param[1].button() == Qt.LeftButton):
218
            self._vertices.append(param[2])
219
        elif ('mouseMoveEvent' == param[0]):
220
            self._pt = param[2]
221
        elif ('mouseReleaseEvent' == param[0]) and (param[1].button() == Qt.RightButton):
222
            self.isCreated = True
223

    
224
    '''
225
        @brief  clone an object
226
    '''
227

    
228
    def clone(self):
229
        clone = QEngineeringStreamlineItem()
230
        clone._vertices = copy.deepcopy(self._vertices)
231
        clone.isCreated = self.isCreated
232

    
233
        return clone
234
        
235
    def init(self):
236
        self._vertices = []
237
        self._pt = None
238
        self.isCreated = False
239

    
240
    def set_fittings(self):
241
        from AppDocData import AppDocData
242
        from Fitting import Fitting
243

    
244
        app_doc_data = AppDocData.instance()
245
        fittings_input = app_doc_data.get_fittings_input(self.uid)
246

    
247
        fittings = {}
248
        fitting_equivalent_item = []
249
        fitting_crane_k_item = []
250
        fitting_2_k_item = []
251

    
252
        for fitting in fittings_input:
253
            uid = fitting[0]
254
            method = fitting[1]
255
            sub_size = fitting[2]
256
            angle = fitting[3]
257
            count = fitting[4]
258

    
259
            if method == 'Equivalent_Length':
260
                fitting_equivalent_item.append(Fitting(uid, sub_size, angle, count))
261
                fittings[method] = fitting_equivalent_item
262
            elif method == 'CraneK':
263
                fitting_crane_k_item.append(Fitting(uid, sub_size, angle, count))
264
                fittings[method] = fitting_crane_k_item
265
            elif method == '2-K':
266
                fitting_2_k_item.append(Fitting(uid, sub_size, angle, count))
267
                fittings[method] = fitting_2_k_item
268

    
269
        self.fittings = fittings
270
    '''
271
        @build  build path
272
        @author humkyung
273
        @date   2018.04.23
274
    '''
275

    
276
    def build_path(self):
277
        if not self._vertices or len(self._vertices) < 2:
278
            return
279

    
280
        try:
281
            if self.connectors:
282
                # re-positioning vertex of stream line
283
                self._vertices = []
284

    
285
                self._vertices.append(self.connectors[0].center())
286
                dx = self.connectors[-1].center()[0] - self._vertices[0][0]
287
                dy = self.connectors[-1].center()[1] - self._vertices[0][1]
288
                if (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'DOWN') and \
289
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'LEFT'):
290
                    if dx >= 0 and dy > 0:
291
                        self._vertices.append((self._vertices[0][0], self._vertices[0][1] + dy))
292
                    elif dx < 0 <= dy:
293
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
294
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
295
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
296
                    elif dx < 0 and dy < 0:
297
                        self._vertices.append(
298
                            (self._vertices[0][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
299
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
300
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
301
                    elif dx > 0 > dy:
302
                        self._vertices.append(
303
                            (self._vertices[0][0], self._vertices[0][1] + QEngineeringStreamlineItem.OFFSET))
304
                        self._vertices.append((self._vertices[-1][0] + dx * 0.5, self._vertices[-1][1]))
305
                        self._vertices.append((self._vertices[-1][0], self.connectors[-1].center()[1]))
306
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'DOWN') and \
307
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'RIGHT'):
308
                    if dx >= 0 and dy < 0:
309
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
310
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
311
                        self._vertices.append((self._vertices[-1][0],
312
                                               self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
313
                    elif dx < 0 and dy < 0:
314
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
315
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
316
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
317
                    elif dx < 0 and dy >= 0:
318
                        self._vertices.append((self._vertices[0][0], self._vertices[-1][1] + dy))
319
                    elif dx >= 0 and dy >= 0:
320
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
321
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
322
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
323
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'DOWN') and \
324
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'UP'):
325
                    if dx >= 0 and dy < 0:
326
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
327
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
328
                        self._vertices.append((self._vertices[-1][0],
329
                                               self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET*2))
330
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
331
                    elif dx < 0 and dy < 0:
332
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
333
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
334
                        self._vertices.append((self._vertices[-1][0],
335
                                               self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET * 2))
336
                        self._vertices.append((self._vertices[-1][0] + dx * 0.5, self._vertices[-1][1]))
337
                    elif dx < 0 and dy >= 0:
338
                        self._vertices.append((self._vertices[0][0], self._vertices[-1][1] + dy*0.5))
339
                        self._vertices.append((self._vertices[0][0] + dx, self._vertices[-1][1]))
340
                    elif dx >= 0 and dy >= 0:
341
                        self._vertices.append((self._vertices[0][0], self._vertices[-1][1] + dy * 0.5))
342
                        self._vertices.append((self._vertices[0][0] + dx, self._vertices[-1][1]))
343
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'DOWN') and \
344
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'DOWN'):
345
                    if dx >= 0 and dy < 0:
346
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
347
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
348
                    elif dx < 0 and dy < 0:
349
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + QEngineeringStreamlineItem.OFFSET))
350
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
351
                    elif dx < 0 and dy >= 0:
352
                        self._vertices.append((self._vertices[0][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
353
                        self._vertices.append((self._vertices[0][0] + dx, self._vertices[-1][1]))
354
                    elif dx >= 0 and dy >= 0:
355
                        self._vertices.append((self._vertices[0][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
356
                        self._vertices.append((self._vertices[0][0] + dx, self._vertices[-1][1]))
357
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'UP') and \
358
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'LEFT'):
359
                    if dx >= 0 and dy < 0:
360
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
361
                    elif dx >= 0 and dy >= 0:
362
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
363
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
364
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
365
                    elif dx < 0 and dy >= 0:
366
                        self._vertices.append(
367
                            (self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
368
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET , self._vertices[-1][1]))
369
                        self._vertices.append(
370
                            (self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
371
                    else:
372
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
373
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
374
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
375
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'UP') and \
376
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'RIGHT'):
377
                    if dx >= 0 and dy < 0:
378
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
379
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
380
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy * 0.5))
381
                    elif dx < 0 and dy < 0:
382
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
383
                    elif dx < 0 and dy >= 0:
384
                        self._vertices.append(
385
                            (self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
386
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
387
                        self._vertices.append(
388
                            (self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
389
                    else:
390
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
391
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
392
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
393
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'UP') and \
394
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'DOWN'):
395
                    if dy < 0:
396
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy * 0.5))
397
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
398
                    else:
399
                        self._vertices.append(
400
                            (self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
401
                        self._vertices.append((self._vertices[-1][0] + dx * 0.5, self._vertices[-1][1]))
402
                        self._vertices.append((self._vertices[-1][0],
403
                                               self.connectors[-1].center()[1] + QEngineeringStreamlineItem.OFFSET))
404
                        self._vertices.append((self._vertices[-1][0] + dx * 0.5, self._vertices[-1][1]))
405
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'UP') and \
406
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'UP'):
407
                    if dx >= 0 and dy < 0:
408
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
409
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
410
                    elif dx < 0 and dy < 0:
411
                        self._vertices.append(
412
                            (self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
413
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
414
                    elif dx < 0 and dy >= 0:
415
                        self._vertices.append(
416
                            (self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
417
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
418
                    else:
419
                        self._vertices.append(
420
                            (self._vertices[-1][0], self._vertices[-1][1] - QEngineeringStreamlineItem.OFFSET))
421
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
422
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'RIGHT') and \
423
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'LEFT'):
424
                    if dx >= 0:
425
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
426
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
427
                    else:
428
                        self._vertices.append(
429
                            (self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
430
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
431
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET*2,
432
                                               self._vertices[-1][1]))
433
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
434
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'RIGHT') and \
435
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'DOWN'):
436
                    if dx >= 0 and dy < 0:
437
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
438
                    elif dx < 0 and dy < 0:
439
                        self._vertices.append((self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
440
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
441
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
442
                    elif dx < 0 and dy >= 0:
443
                        self._vertices.append(
444
                            (self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
445
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
446
                        self._vertices.append(
447
                            (self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
448
                    else:
449
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
450
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
451
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
452
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'RIGHT') and \
453
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'UP'):
454
                    if dx >= 0 and dy < 0:
455
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
456
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
457
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
458
                    elif dx < 0 and dy < 0:
459
                        self._vertices.append((self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
460
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
461
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
462
                    elif dx < 0 and dy >= 0:
463
                        self._vertices.append(
464
                            (self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
465
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
466
                        self._vertices.append(
467
                            (self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
468
                    else:
469
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
470
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'RIGHT') and \
471
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'RIGHT'):
472
                    if dx >= 0 and dy < 0:
473
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
474
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
475
                    elif dx < 0 and dy < 0:
476
                        self._vertices.append((self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
477
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
478
                    elif dx < 0 and dy >= 0:
479
                        self._vertices.append(
480
                            (self._vertices[-1][0] + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
481
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
482
                    else:
483
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
484
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
485
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'LEFT') and \
486
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'LEFT'):
487
                    if dx >= 0 and dy < 0:
488
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
489
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
490
                    elif dx < 0 and dy < 0:
491
                        self._vertices.append((self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
492
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
493
                    elif dx < 0 and dy >= 0:
494
                        self._vertices.append(
495
                            (self._vertices[-1][0] + dx - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
496
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
497
                    else:
498
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
499
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
500
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'LEFT') and \
501
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'RIGHT'):
502
                    if dx >= 0 and dy < 0:
503
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
504
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
505
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET*2, self._vertices[-1][1]))
506
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
507
                    elif dx < 0 and dy < 0:
508
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
509
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
510
                    elif dx < 0 and dy >= 0:
511
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
512
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
513
                    else:
514
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
515
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
516
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET*2, self._vertices[-1][1]))
517
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
518
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'LEFT') and \
519
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'UP'):
520
                    if dx >= 0 and dy < 0:
521
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
522
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
523
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
524
                    elif dx < 0 and dy < 0:
525
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
526
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy - QEngineeringStreamlineItem.OFFSET))
527
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
528
                    elif dx < 0 and dy >= 0:
529
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
530
                    else:
531
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
532
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
533
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
534
                elif (self.connectors[0].connectedItem and self.connectors[0].connectedItem.direction == 'LEFT') and \
535
                        (self.connectors[-1].connectedItem and self.connectors[-1].connectedItem.direction == 'DOWN'):
536
                    if dx >= 0 and dy < 0:
537
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
538
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy*0.5))
539
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
540
                    elif dx < 0 and dy < 0:
541
                        self._vertices.append((self._vertices[-1][0] + dx, self._vertices[-1][1]))
542
                    elif dx < 0 and dy >= 0:
543
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
544
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
545
                        self._vertices.append((self._vertices[-1][0] + dx*0.5, self._vertices[-1][1]))
546
                    else:
547
                        self._vertices.append((self._vertices[-1][0] - QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
548
                        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy + QEngineeringStreamlineItem.OFFSET))
549
                        self._vertices.append((self._vertices[-1][0] + dx + QEngineeringStreamlineItem.OFFSET, self._vertices[-1][1]))
550
                else:
551
                    self._vertices.append((self._vertices[0][0] + dx * 0.5, self._vertices[0][1]))
552
                    self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
553

    
554
                self._vertices.append(self.connectors[-1].center())
555
                # up to here
556

    
557
            path = QPainterPath()
558
            path.moveTo(self._vertices[0][0], self._vertices[0][1])
559

    
560
            max_length = 0
561
            max_length_line = [None, None]
562
            for i in range(1, len(self._vertices)):
563
                path.lineTo(self._vertices[i][0], self._vertices[i][1])
564
                dx = self._vertices[i][0] - self._vertices[i-1][0]
565
                dy = self._vertices[i][1] - self._vertices[i-1][1]
566
                if dx*dx + dy*dy > max_length:
567
                    max_length = dx*dx + dy*dy
568
                    max_length_line[0] = self._vertices[i-1]
569
                    max_length_line[1] = self._vertices[i]
570

    
571
            self.setPath(path)
572
            self.isCreated = True
573

    
574
            if self._stream_no_text:
575
                doc = self._stream_no_text.document()
576
                option = doc.defaultTextOption()
577
                option.setAlignment(Qt.AlignCenter)
578
                doc.setDefaultTextOption(option)
579
                if max_length_line[0] is not None and max_length_line[1] is not None:
580
                    self._stream_no_text.setTextWidth(doc.idealWidth())
581
                    dx = max_length_line[0][0] - max_length_line[1][0]
582
                    dy = max_length_line[0][1] - max_length_line[1][1]
583
                    if abs(dx) >= abs(dy):
584
                        x = (max_length_line[0][0] + max_length_line[1][0] - self._stream_no_text.textWidth())*0.5
585
                        y = (max_length_line[0][1] + max_length_line[1][1])*0.5
586
                        self._stream_no_text.setPos(QPointF(x, y))
587
                    else:
588
                        x = (max_length_line[0][0] + max_length_line[1][0]) * 0.5
589
                        y = (max_length_line[0][1] + max_length_line[1][1] - self._stream_no_text.textWidth()) * 0.5
590
                        self._stream_no_text.setPos(QPointF(x, y))
591

    
592
            self.update_arrow()
593
        except Exception as ex:
594
            from App import App
595
            from AppDocData import MessageType
596

    
597
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
598
                                                           sys.exc_info()[-1].tb_lineno)
599
            App.mainWnd().addMessage.emit(MessageType.Error, message)
600

    
601
    '''
602
        @brief      return bounding rectangle of polyline
603
        @author     humkyung
604
        @date       2018.07.23
605
    '''
606

    
607
    def boundingRect(self):
608
        rect = QRectF()
609
        
610
        if self.isCreated:
611
            rect = self.path().boundingRect()
612
            rect = QRectF(rect.left() - 5, rect.top() - 5, rect.width() + 10, rect.height() + 10)
613
        else:
614
            minX = None
615
            minY = None
616
            maxX = None
617
            maxY = None
618
            for pt in self._vertices:
619
                if minX is None or pt[0] < minX:
620
                    minX = pt[0]
621
                if minY is None or pt[1] < minY:
622
                    minY = pt[1]
623
                
624
                if maxX is None or pt[0] > maxX:
625
                    maxX = pt[0]
626
                if maxY is None or pt[1] > maxY:
627
                    maxY = pt[1]
628
            
629
            if self._pt is not None:
630
                if minX is None or self._pt[0] < minX:
631
                    minX = self._pt[0]
632
                if minY is None or self._pt[1] < minY:
633
                    minY = self._pt[1]
634
                
635
                if maxX is None or self._pt[0] > maxX:
636
                    maxX = self._pt[0]
637
                if maxY is None or self._pt[1] > maxY:
638
                    maxY = self._pt[1]
639

    
640
            if minX is not None and minY is not None and maxX is not None and maxY is not None:
641
                rect = QRectF(minX - 5, minY - 5, maxX - minX + 10, maxY - minY + 10)
642
        
643
        return rect
644

    
645
    '''
646
        @brief      
647
        @author     humkyung
648
        @date       2018.07.26
649
    '''
650

    
651
    def onMouseMoved(self, event, scenePos):
652
        from SymbolSvgItem import SymbolSvgItem
653
        from EngineeringConnectorItem import QEngineeringConnectorItem
654

    
655
        # get connection point near by mouse point
656
        pt = (scenePos.x(), scenePos.y())
657
        item = self.scene().itemAt(scenePos, QTransform())
658
        if (item is not None) and (type(item) is SymbolSvgItem):
659
            connPt = item.getConnectionPointCloseTo(pt, 5)
660
            if connPt is not None: pt = connPt
661
        elif (item is not None) and (type(item) is QEngineeringConnectorItem):
662
            pt = item.center()
663
        # up to here
664
            
665
        del self._vertices[1:]
666
        dx = pt[0] - self._vertices[0][0]
667
        dy = pt[1] - self._vertices[0][1]
668
        self._vertices.append((self._vertices[0][0] + dx*0.5, self._vertices[0][1]))
669
        self._vertices.append((self._vertices[-1][0], self._vertices[-1][1] + dy))
670
        self._vertices.append(pt)
671

    
672
        self.build_path()
673
        self.update()
674
        
675
    def hoverEnterEvent(self, event):
676
        """ hilight item and it's children """
677
        self.highlight(True)
678

    
679
    def hoverLeaveEvent(self, event):
680
        """ unhighlight item """
681
        self.highlight(False)
682

    
683
    def highlight(self, flag):
684
        self.hover = flag 
685
        self.setZValue(QEngineeringAbstractItem.HOVER_ZVALUE) if flag else \
686
            self.setZValue(QEngineeringStreamlineItem.ZVALUE)
687
        self.update()
688

    
689
    def paint(self, painter, option, widget):
690
        """ override paint method """
691
        if self.isSelected():
692
            hilightColor = QColor(255, 0, 0, 127)
693
            focuspen = QPen(Qt.DotLine)
694
            focuspen.setColor(hilightColor)
695
            focuspen.setWidthF(3)
696
            painter.setPen(focuspen)
697
            painter.drawPath(self.path())
698
        else:
699
            color = self.getColor()
700
            self.setColor(color)
701
            QGraphicsPathItem.paint(self, painter, option, widget)
702
        
703
    '''
704
        @brief      Return real item position
705
        @authro     Jeongwoo
706
        @date       2018.05.29
707
    '''
708

    
709
    def boundingRectOnScene(self):
710
        rect = self.boundingRect()
711
        sp = self.startPoint()
712
        rect.moveTo(sp[0], sp[1])
713
        return rect
714

    
715
    '''
716
        @brief      Set Color. Override QEngineeringAbstractItem's
717
        @author     Jeongwoo
718
        @date       2018.05.11
719
        @history    2018.05.11  Jeongwoo    Add self.setPen() Method
720
        @history    humkyung 2018.05.13 call setPen method to apply changed color
721
    '''
722

    
723
    def setColor(self, color):
724
        c = QColor()
725
        c.setNamedColor(color)
726
        _pen = self.pen()
727
        _pen.setColor(c)
728
        self.setPen(_pen)
729
        self.update()
730

    
731
    def on_symbol_pos_changed(self, symbol):
732
        """ rebuild stream line because symbol position is changed """
733
        if self.connectors[0].connectedItem is not None: self.connectors[0].setPos(
734
            self.connectors[0].connectedItem.center())
735
        if self.connectors[-1].connectedItem is not None: self.connectors[-1].setPos(
736
            self.connectors[-1].connectedItem.center())
737
        self.on_connector_pos_changed(None)
738

    
739
    def on_connector_pos_changed(self, connector):
740
        """ rebuild stream line """
741

    
742
        self.build_path()
743
        self.update()
744

    
745
    def mouseDoubleClickEvent(self, event):
746
        from StreamDataDialog import QStreamDataDialog
747
        try:
748

    
749
            dialog = QStreamDataDialog()
750
            res = dialog.showDialog(self)
751
            if res:
752
                self.load_HMB()
753

    
754
        except Exception as ex:
755
            from App import App
756
            from AppDocData import MessageType
757

    
758
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
759
                                                           sys.exc_info()[-1].tb_lineno)
760
            App.mainWnd().addMessage.emit(MessageType.Error, message)
761

    
762
    def load_HMB(self):        
763
        from App import App 
764

    
765
        App.mainWnd().load_HMB()
766
        
767
    def keyPressEvent(self, event):
768
        from App import App
769
        from AppDocData import AppDocData
770
        if not self.isSelected(): return
771

    
772
        if event.key() == Qt.Key_Delete: 
773
            self.transfer.onRemoved.emit(self)
774
        elif event.key() == Qt.Key_QuoteLeft:
775
            self.mouseDoubleClickEvent(event)    
776
           
777
    def toSql(self):
778
        """ convert valve data to sql query """
779
        import uuid
780
        from AppDocData import AppDocData
781

    
782
        res = []
783
        app_doc_data = AppDocData.instance()
784

    
785
        try:
786
            symbolInfo = app_doc_data.getSymbolByQuery('name', 'Stream Line')
787
            dbUid = symbolInfo.uid
788
            uid = self.uid
789

    
790
            cols = ['UID', 'Symbols_UID', 'Name']
791
            values = ['?', '?', '?']
792
            param = [str(uid), str(dbUid), str(self.stream_no)]
793
            sql = 'insert or replace into Components({}) values({})'.format(','.join(cols), ','.join(values))
794
            res.append((sql, tuple(param)))
795

    
796
            # save vertices to database
797
            index = 1
798
            for vertex in self._vertices:
799
                if index == 1 and self.connectors[0].connectedItem is not None:
800
                    cols = ['UID', 'Components_UID', '[Index]', 'X', 'Y', 'ConnectedItem_UID']
801
                    values = ['?', '?', '?', '?', '?', '?']
802
                    param = [str(uuid.uuid4()), str(uid), index, vertex[0], vertex[1],
803
                             str(self.connectors[0].connectedItem.uid)]
804
                elif index == len(self._vertices) and self.connectors[1].connectedItem is not None:
805
                    cols = ['UID', 'Components_UID', '[Index]', 'X', 'Y', 'ConnectedItem_UID']
806
                    values = ['?', '?', '?', '?', '?', '?']
807
                    param = [str(uuid.uuid4()), str(uid), index, vertex[0], vertex[1],
808
                             str(self.connectors[1].connectedItem.uid)]
809
                else:
810
                    cols = ['UID', 'Components_UID', '[Index]', 'X', 'Y']
811
                    values = ['?', '?', '?', '?', '?']
812
                    param = [str(uuid.uuid4()), str(uid), index, vertex[0], vertex[1]]
813

    
814
                sql = 'insert or replace into Points({}) values({})'.format(','.join(cols), ','.join(values))
815

    
816
                res.append((sql, tuple(param)))
817
                index += 1
818
            # save fittings to database
819
            for method in self.fittings:
820
                cols = ['UID', 'Components_UID', 'Fittings_UID', 'Method', 'Sub_Size', 'Angle', 'Count']
821
                values = ['?', '?', '?', '?', '?', '?', '?']
822

    
823
                for fitting in self.fittings[method]:
824
                    param = [str(uuid.uuid4()), str(uid), fitting.uid, method, fitting.sub_size, fitting.angle, fitting.count]
825

    
826
                    sql = 'insert or replace into Fittings_Input({}) values({})'.format(','.join(cols), ','.join(values))
827
                    res.append((sql, tuple(param)))
828
        except Exception as ex:
829
            from App import App
830
            from AppDocData import MessageType
831

    
832
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
833
                                                          sys.exc_info()[-1].tb_lineno)
834
            App.mainWnd().addMessage.emit(MessageType.Error, message)
835

    
836
        return res
837

    
838
    @staticmethod 
839
    def fromDatabase(componentInfos):
840
        from AppDocData import AppDocData
841

    
842
        item = None
843
        try:
844
            app_doc_data = AppDocData.instance()
845

    
846
            uid = componentInfos[0][0]              #uid@Components
847

    
848
            item = QEngineeringStreamlineItem(uid)
849
            hmb_data = app_doc_data.activeDrawing.hmbTable.get_hmb_data(uid)
850
            item.stream_no = int(hmb_data.stream_no) if hmb_data else 1 # stream no
851

    
852
            pointsUids = []
853
            for componentInfo in componentInfos:     
854
                pointsUid = componentInfo[11]           # uid@Points           
855
                x = componentInfo[13]                   # X@Points
856
                y = componentInfo[14]                   # Y@Points
857

    
858
                pointsUids.append(pointsUid)
859
                item._vertices.append((x, y))
860

    
861
            connectorItems = [componentInfos[0][15], componentInfos[-1][15]]
862

    
863
            item.setVisible(False)
864
            item.build_connectors(connectorItems, pointsUids)
865
            item.build_path()
866
            item.set_fittings()
867
            item.update()
868

    
869
        except Exception as ex:
870
            from App import App 
871
            from AppDocData import MessageType
872

    
873
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
874
                                                          sys.exc_info()[-1].tb_lineno)
875
            App.mainWnd().addMessage.emit(MessageType.Error, message)
876

    
877
        return item
878

    
879

    
880
'''
881
    @brief      The class transfer pyqtSignal Event. Cause Subclass of QGraphicsRectItem can't use pyqtSignal
882
    @author     Jeongwoo
883
    @date       2018.06.18
884
'''
885

    
886

    
887
class Transfer(QObject):
888
    onRemoved = pyqtSignal(QGraphicsItem)
889

    
890
    def __init__(self, parent = None):
891
        QObject.__init__(self, parent)
클립보드 이미지 추가 (최대 크기: 500 MB)