프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / QResultTreeWidget.py @ ef580b4f

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

1
try:
2
    from PyQt5.QtCore import *
3
    from PyQt5.QtGui import *
4
    from PyQt5.QtWidgets import *
5
except ImportError:
6
    try:
7
        from PyQt4.QtCore import *
8
        from PyQt4.QtGui import *
9
    except ImportError:
10
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
11
from SymbolSvgItem import SymbolSvgItem
12
from QEngineeringTextItem import QEngineeringTextItem
13
from QEngineeringNoteItem import QEngineeringNoteItem
14
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
15
from AppDocData import AppDocData
16
import os
17
import re
18

    
19
class QResultTreeWidget(QTreeWidget):
20
    TREE_DATA_ROLE = Qt.ToolTipRole
21

    
22
    #Add Signal
23
    singleClicked = pyqtSignal(SymbolSvgItem)
24
    noteNoSingleClicked = pyqtSignal(str, list)
25
    lineNoSingleClicked = pyqtSignal(QEngineeringLineNoTextItem)
26

    
27
    '''
28
        @history    2018.05.11  Jeongwoo    Add Context Menu settings
29
    '''
30
    def __init__(self, imageViewer):
31
        QTreeWidget.__init__(self)
32
        self.itemClicked.connect(self.itemClickEvent)
33
        self.imageViewer = imageViewer
34
        self.scene = imageViewer.scene
35
        self.root = None
36
        self.setContextMenuPolicy(Qt.CustomContextMenu)
37
        self.customContextMenuRequested.connect(self.openContextMenu)
38
            
39
    '''
40
        @brief      Show Context Menu
41
        @author     Jeongwoo
42
        @date       18.05.11
43
    '''
44
    def openContextMenu(self, position):
45
        indexes = self.selectedIndexes()
46
        itemPosition = self.mapTo(self, position)
47
        item = self.itemAt(itemPosition)
48
        data = item.data(0, self.TREE_DATA_ROLE)
49
        if len(indexes) > 0 and data is not None and type(data) is QEngineeringLineNoTextItem:
50
            index = indexes[0]
51
            menu = QMenu()
52
            pickColorAction = QAction(self.tr("색상 설정"))
53
            pickColorAction.triggered.connect(lambda : self.pickColorClickEvent(item))
54
            menu.addAction(pickColorAction)
55
            menu.exec_(self.viewport().mapToGlobal(position))
56

    
57
    '''
58
        @brief      Pick Color for Line No
59
        @author     Jeongwoo
60
        @date       18.05.11
61
        @history    18.05.14    Jeongwoo    Change method to change color by changeTreeWidgetItemColorRecursively()
62
    '''
63
    def pickColorClickEvent(self, lineNoTreeWidgetItem):
64
        ''''''
65
        color = QColorDialog.getColor() # Dialog returns QColor
66
        
67
        if color is not None:
68
            lineNoTreeWidgetItem.setForeground(0, QBrush(color))
69
            lineNoTreeWidgetItem.setFont(0, lineNoTreeWidgetItem.font(0))
70
            lineNoItem = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
71
            lineNoItem.setColor(color.name())
72
            connectedItems = lineNoItem.getConnectedItems()
73
            if connectedItems is not None:
74
                for connectedItem in connectedItems:
75
                    connectedItem.setColor(color.name())
76
                self.changeTreeWidgetItemColorRecursively(lineNoTreeWidgetItem, color)
77

    
78
    '''
79
        @brief      Change Color recursively
80
        @author     Jeongwoo
81
        @date       18.05.14
82
    '''
83
    def changeTreeWidgetItemColorRecursively(self, item, color):
84
        for index in range(item.childCount()):
85
            child = item.child(index)
86
            child.setForeground(0, QBrush(color))
87
            child.setFont(0, child.font(0))
88
            self.changeTreeWidgetItemColorRecursively(child, color)
89

    
90
    '''
91
        @brief      Clear TreeWidget and Set Current PID
92
        @author     Jeongwoo
93
        @date       18.04.11
94
        @history    2018.04.26  Jeongwoo    Add Child [SYMBOLS, NOTES] into root item
95
                    2018.05.09  Jeongwoo    Change method to add default tree items
96
    '''
97
    def setCurrentPID(self, baseName):
98
        self.clear()
99
        self.root = QTreeWidgetItem(self, [os.path.splitext(baseName)[0]])
100
        self.root.addChild(QTreeWidgetItem(['EQUIPMENTS']))
101
        self.root.addChild(QTreeWidgetItem(['SYMBOLS']))
102
        self.root.addChild(QTreeWidgetItem(['NOTES']))
103

    
104
    '''
105
        @brief  create tree item for pipe run if need
106
        @author humkyung
107
        @date   2018.05.15
108
    '''
109
    def addPipeRunTreeItemIfNeed(self, lineNoTreeItem, pipeRun):
110
        for index in range(lineNoTreeItem.childCount()):
111
            treeItem = lineNoTreeItem.child(index)
112
            itemData = treeItem.data(0, self.TREE_DATA_ROLE)
113
            if itemData is not None and itemData == pipeRun.uid:
114
                return treeItem
115

    
116
        runItem = QTreeWidgetItem(['RUNS {}'.format(lineNoTreeItem.childCount()+1)])
117
        runItem.setData(0, self.TREE_DATA_ROLE, pipeRun.uid)
118
        lineNoTreeItem.addChild(runItem)
119

    
120
        return runItem
121

    
122
    '''
123
        @brief      add a tree item
124
        @author     humkyung
125
        @date       2018.04.17
126
        @history    humkyung 2018.04.19 treat a case parent is changed
127
                    Jeongwoo 2018.04.26 QEngineeringTextItem → QEngineeringLineNoTextItem
128
                                        Insert if-statement for QEngineeringNoteItem
129
                                        Add if-statement for QEngineeringLineNoTextItem
130
                    Jeongwoo 2018.05.11 Set color when SymbolSvgItem moved into new parent(Line No)
131
    '''
132
    def addTreeItem(self, parent, child):
133
        item = None
134
        if (not hasattr(child, 'treeItem')) or (child.treeItem is None):
135
            if issubclass(type(child), SymbolSvgItem):
136
                if AppDocData.instance().isEquipmentByType(child.type):
137
                    symbolsRootItem = self.findItems('EQUIPMENTS', Qt.MatchExactly|Qt.MatchRecursive, 0)
138
                    symbolsRootItem = symbolsRootItem[0]
139
                    item = QTreeWidgetItem(symbolsRootItem, [child.name])
140
                else:
141
                    symbolsRootItem = self.findItems('SYMBOLS', Qt.MatchExactly|Qt.MatchRecursive, 0)
142
                    symbolsRootItem = symbolsRootItem[0]
143
                    item = QTreeWidgetItem(symbolsRootItem, [child.name])
144
                iconPath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), child.type , child.name + ".svg")
145
                item.setIcon(0, QIcon(iconPath))
146
                item.setData(0, self.TREE_DATA_ROLE, child)
147
                child.treeItem = item
148
                symbolsRootItem.addChild(item)
149
            elif type(child) is QEngineeringLineNoTextItem:
150
                item = QTreeWidgetItem([child.text()])
151
                item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
152
                item.setData(0, self.TREE_DATA_ROLE, child)
153
                item.setCheckState(0, Qt.Unchecked)
154
                child.treeItem = item
155
                self.root.insertChild(0, item)
156
            elif (type(child) is QEngineeringNoteItem):
157
                item = QTreeWidgetItem([child.text()])
158
                item.setData(0, self.TREE_DATA_ROLE, child)
159
                child.treeItem = item
160
                if parent is not None:
161
                    parent.addChild(item)
162
        elif issubclass(type(child), SymbolSvgItem):  # change item's parent
163
            foundItems = self.findItems(child.name, Qt.MatchExactly|Qt.MatchRecursive, 0)
164
            if foundItems is not None:
165
                for item in foundItems:
166
                    data = item.data(0, self.TREE_DATA_ROLE)
167
                    if data is not None and (data == child) and (parent is not item.parent()):
168
                        parentData = parent.data(0, self.TREE_DATA_ROLE)
169
                        if type(parentData) is QEngineeringLineNoTextItem:
170
                            for index in range(len(parentData.runs)):
171
                                runGroup = parentData.runs[index]
172
                                if data in runGroup.items:
173
                                    item.parent().removeChild(item) # remove item from original parent
174
                                    runItem = self.addPipeRunTreeItemIfNeed(parent, runGroup) #parent.child(index)
175
                                    brush = parent.foreground(0)
176
                                    item.setForeground(0, brush)
177
                                    item.data(0, self.TREE_DATA_ROLE).setColor(brush.color().name())
178
                                    item.setFont(0, item.font(0))
179
                                    runItem.addChild(item)
180
                                else:
181
                                    print(item.text(0) + " Not Found on " + parent.text(0))
182
                        #brush = parent.foreground(0)
183
                        #item.setForeground(0, brush)
184
                        #item.data(0, self.TREE_DATA_ROLE).setColor(brush.color().name())
185
                        #item.setFont(0, item.font(0))
186
                        #parent.addChild(item)
187
                        break
188
        elif type(child) is QEngineeringLineNoTextItem:
189
            foundItems = self.findItems(child.text(), Qt.MatchExactly|Qt.MatchRecursive, 0)
190
            if foundItems is not None:
191
                for item in foundItems:
192
                    data = item.data(0, self.TREE_DATA_ROLE)
193
                    if data is not None and (data == child):
194
                        #for index in range(len(data.runs)):
195
                        #    item.addChild(QTreeWidgetItem(['RUNS' + str(index+1)]))
196
                        return item
197

    
198
        return item
199

    
200
    '''
201
        @brief      Scene Changed Listener
202
        @author     Jeongwoo
203
        @date       18.04.11
204
        @history    Jeongwoo 2018.04.25 Add QEngineeringNoteItem to list for loop  / NOT QEngineeringTextItem
205
                    Jeongwoo 2018.04.26 Change changedSceneItems conditions in loop (QEngineeringTextItem → QEngineeringLineNoTextItem)
206
    '''
207
    lastSceneItems = None
208
    def sceneChanged(self, sceneItems):
209
        changedSceneItems = [item for item in sceneItems if ((issubclass(type(item), SymbolSvgItem)) or (type(item) is QEngineeringNoteItem) or (type(item) is QEngineeringLineNoTextItem)) 
210
                            and (not hasattr(item, 'treeItem') or item.treeItem is None)] # Sublist includes SymbolSvgItem
211
        self.initResultTreeWidget(changedSceneItems)
212
            
213
    '''
214
        @brief      Initialize TreeWidget
215
                    Tree Item Clear and Add Item
216
        @author     Jeongwoo
217
        @date       2018.04.11
218
        @history    2018.04.12 Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
219
        @history    2018.04.17 humkyung NOT remove child of root
220
                    2018.04.25 Jeongwoo     Add QEngineeringNoteItem Child
221
                    2018.04.26 Jeongwoo     Change method to insert child
222
    '''
223
    def initResultTreeWidget(self, items):
224
        for item in items:
225
            if (type(item) is QEngineeringNoteItem):
226
                notesRootItem = self.findItems('NOTES', Qt.MatchExactly|Qt.MatchRecursive, 0)
227
                notesRootItem = notesRootItem[0]
228

    
229
                self.addTreeItem(notesRootItem, item)
230
            else:
231
                self.addTreeItem(self.root, item)
232
                    
233
        notesRootItem = self.findItems('NOTES', Qt.MatchExactly|Qt.MatchRecursive, 0)
234
        if notesRootItem is not None and len(notesRootItem) > 0:
235
            notesRootItem[0].sortChildren(0, Qt.AscendingOrder)
236
        self.expandAll()
237
        
238
    '''
239
        @brief      TreeWidget Item click listener
240
        @author     Jeongwoo
241
        @date       18.04.11
242
        @history    18.04.12    Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
243
                    18.04.13    Jeongwoo    Signal 'singleClicked' emit SymbolSvgItem
244
                                            CenterOn() with Symbol's center
245
                    18.04.25    Jeongwoo    Add QEngineeringNoteItem Click event
246
                    18.04.26    Jeongwoo    QEngineeringTextItem → QEngineeringLineNoTextItem
247
                    18.04.27    Jeongwoo    Find NOTE Contents when NOTE No. Clicked
248
                                            Move singClicked to if-statement type(itemData) is SymbolSvgItem:
249
                    18.05.10    Jeongwoo    Add lineNoSingleClicked emit
250
    '''
251
    lastClickedItem = None
252
    def itemClickEvent(self, item, columnNo, isSvgClick = False):
253
        print("Item " + item.text(0) + " clicked")
254
        itemData = item.data(0, self.TREE_DATA_ROLE)
255
        
256
        if self.lastClickedItem is not None:
257
            self.scene.removeItem(self.lastClickedItem)
258

    
259
        if itemData is not None: ## Not PID Name
260
            if issubclass(type(itemData), SymbolSvgItem):
261
                ## Draw rectangle on selected symbol
262
                rect = itemData.sceneBoundingRect()
263
                graphicItem = self.scene.addRect(rect.left(), rect.top(), rect.width(), rect.height(), QPen(QColor(255,255,0,100)), QBrush(QColor(255,255,0,100)))
264
                if isSvgClick == False:
265
                    self.imageViewer.centerOn(rect.center())
266
                ## Send new event to imageViewer's zoomImage Method
267
                self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
268
                self.lastClickedItem = graphicItem
269
                
270
                self.singleClicked.emit(itemData)
271
            elif type(itemData) is QEngineeringLineNoTextItem:
272
                rect = itemData.sceneBoundingRect()
273
                graphicItem = self.scene.addRect(rect.left(), rect.top(), rect.width(), rect.height(), QPen(QColor(255,255,0,100)), QBrush(QColor(255,255,0,100)))
274
                if isSvgClick == False:
275
                    self.imageViewer.centerOn(rect.center())
276
                ## Send new event to imageViewer's zoomImage Method
277
                self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
278
                self.lastClickedItem = graphicItem
279

    
280
                self.lineNoSingleClicked.emit(itemData)
281
            elif type(itemData) is QEngineeringNoteItem:
282
                rect = itemData.sceneBoundingRect()
283
                graphicItem = self.scene.addRect(rect.left(), rect.top(), rect.width(), rect.height(), QPen(QColor(255,255,0,100)), QBrush(QColor(255,255,0,100)))
284
                if isSvgClick == False:
285
                    self.imageViewer.centerOn(rect.center())
286
                ## Send new event to imageViewer's zoomImage Method
287
                self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
288
                self.lastClickedItem = graphicItem
289
                #noteContentsList = self.findNoteContents(itemData.text())
290
                noteContentsList = itemData.findNoteContents(itemData.text())
291

    
292
                self.noteNoSingleClicked.emit(itemData.text(), noteContentsList)
293
                        
294

    
295
    '''
296
        @brief  find item which has data is given item
297
        @author humkyung
298
        @date   2018.04.23
299
    '''
300
    def findItemByData(self, item):
301
        if issubclass(type(item), SymbolSvgItem):
302
            foundItems = self.findItems(item.name, Qt.MatchExactly|Qt.MatchRecursive, 0)
303
            for foundItem in foundItems:
304
                data = foundItem.data(0, self.TREE_DATA_ROLE)
305
                if data is not None and data is item:
306
                    return foundItem
307
        elif type(item) is QEngineeringLineNoTextItem:
308
            foundItems = self.findItems(item.text() , Qt.MatchExactly|Qt.MatchRecursive, 0)
309
            for foundItem in foundItems:
310
                data = foundItem.data(0, self.TREE_DATA_ROLE)
311
                if data is not None and data is item:
312
                    return foundItem
313
        
314
        return None
315

    
316
    '''
317
        @brief      Find QTreeWidgetItem by SymbolSvgItem object
318
        @author     Jeongwoo
319
        @date       18.04.11
320
        @history    18.04.12    Jeongwoo    Change Flags (Qt.MatchExactly → Qt.MatchExactly|Qt.MatchRecursive)
321
                                            Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
322
    '''
323
    @pyqtSlot(SymbolSvgItem)
324
    def findItem(self, item):
325
        if issubclass(type(item), SymbolSvgItem):
326
            foundItems = self.findItems(item.name, Qt.MatchExactly|Qt.MatchRecursive, 0)
327
            if foundItems is not None:
328
                for fItem in foundItems:
329
                    data = fItem.data(0, self.TREE_DATA_ROLE)
330
                    if data is not None and data == item:
331
                        self.setCurrentItem(fItem)
332
                        self.itemClickEvent(fItem, 0, True)
333
                        return
334
        ## Not found
335
        msg = QMessageBox()
336
        msg.setIcon(QMessageBox.Warning)
337
        msg.setText('선택하신 심볼의 데이터를 찾을 수 없습니다.')
338
    
339
    '''
340
        @brief  remove given item
341
        @author humkyung
342
        @date   2018.04.23
343
    '''
344
    @pyqtSlot(QGraphicsItem)
345
    def itemRemoved(self, item):
346
        foundItem = self.findItemByData(item)
347
        if foundItem is not None:
348
            foundItem.parent().removeChild(foundItem)
클립보드 이미지 추가 (최대 크기: 500 MB)