hytos / DTI_PID / DTI_PID / SymbolTreeWidget.py @ d8b09f9f
이력 | 보기 | 이력해설 | 다운로드 (22.5 KB)
1 |
# coding: utf-8
|
---|---|
2 |
""" This is Symbol Tree Widget module """
|
3 |
|
4 |
try:
|
5 |
from PyQt5.QtCore import * |
6 |
from PyQt5.QtGui import * |
7 |
from PyQt5.QtWidgets import * |
8 |
except ImportError: |
9 |
try:
|
10 |
from PyQt4.QtCore import * |
11 |
from PyQt4.QtGui import * |
12 |
except ImportError: |
13 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
14 |
from AppDocData import * |
15 |
import os |
16 |
import sys |
17 |
import SymbolBase |
18 |
import symbol |
19 |
import SymbolEditorDialog |
20 |
import QSymbolDisplayDialog |
21 |
|
22 |
|
23 |
class SearchProxyModel(QSortFilterProxyModel): |
24 |
def setFilterRegExp(self, pattern): |
25 |
if isinstance(pattern, str): |
26 |
pattern = QRegExp( pattern, Qt.CaseInsensitive, QRegExp.FixedString) |
27 |
super(SearchProxyModel, self).setFilterRegExp(pattern) |
28 |
|
29 |
def _accept_index(self, idx): |
30 |
if idx.isValid():
|
31 |
text = idx.data(Qt.DisplayRole) |
32 |
if hasattr(self, 'text') and 'HIDDEN' in self.text.upper() and '(HIDDEN)' in text.upper(): |
33 |
return True |
34 |
elif '(HIDDEN)' in text.upper(): |
35 |
return False |
36 |
|
37 |
if self.filterRegExp().indexIn(text) >= 0: |
38 |
return True |
39 |
for row in range(idx.model().rowCount(idx)): |
40 |
if self._accept_index(idx.model().index(row, 0, idx)): |
41 |
return True |
42 |
return False |
43 |
|
44 |
def filterAcceptsRow(self, source_row, source_parent): |
45 |
idx = self.sourceModel().index(source_row, 0, source_parent) |
46 |
return self._accept_index(idx) |
47 |
|
48 |
|
49 |
class QSymbolTreeWidget(QTreeView): |
50 |
# Add signal
|
51 |
singleClicked = pyqtSignal(SymbolBase.SymbolBase) |
52 |
symbols_loaded = pyqtSignal([SymbolBase.SymbolBase]) |
53 |
TREE_DATA_ROLE = Qt.UserRole |
54 |
|
55 |
def __init__(self): |
56 |
QTreeView.__init__(self)
|
57 |
self.setIconSize(QSize(32, 32)) |
58 |
|
59 |
self.setDragEnabled(True) # enable drag |
60 |
self.initSymbolTreeView()
|
61 |
self.isDoubleClicked = False |
62 |
self.doubleClicked.connect(self.itemDoubleClickEvent) |
63 |
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
64 |
self.customContextMenuRequested.connect(self.openContextMenu) |
65 |
|
66 |
@property
|
67 |
def symbols(self): |
68 |
"""return symbols"""
|
69 |
res = [] |
70 |
|
71 |
try:
|
72 |
tree_item_stack = [self.model().sourceModel().invisibleRootItem()]
|
73 |
while tree_item_stack:
|
74 |
tree_item = tree_item_stack.pop(0)
|
75 |
if tree_item and tree_item.rowCount(): |
76 |
for idx in range(tree_item.rowCount()): |
77 |
child = tree_item.child(idx) |
78 |
tree_item_stack.append(child) |
79 |
elif tree_item and tree_item.data(Qt.UserRole): |
80 |
if type(tree_item.data(Qt.UserRole)) is SymbolBase.SymbolBase and tree_item.data(Qt.UserRole).iType != -1: |
81 |
res.append(tree_item.data(Qt.UserRole)) |
82 |
except Exception as ex: |
83 |
from App import App |
84 |
|
85 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
86 |
sys.exc_info()[-1].tb_lineno)
|
87 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
88 |
|
89 |
return res
|
90 |
|
91 |
def openContextMenu(self, position): |
92 |
"""show context menu"""
|
93 |
item_position = self.mapTo(self, position) |
94 |
index = self.indexAt(item_position)
|
95 |
item = self.model().sourceModel().itemFromIndex(self.model().mapToSource(index)) |
96 |
data = item.data(self.TREE_DATA_ROLE)
|
97 |
|
98 |
advanced = False
|
99 |
app_doc_data = AppDocData.instance() |
100 |
configs = app_doc_data.getAppConfigs('app', 'mode') |
101 |
if configs and 1 == len(configs) and 'advanced' == configs[0].value: |
102 |
advanced = True
|
103 |
|
104 |
indexes = self.selectedIndexes()
|
105 |
if data is not None and type(data) is symbol.SymbolBase: |
106 |
sym = self.getSymbolByItemName(item, 0) |
107 |
text = item.text() |
108 |
if len(indexes) > 0: |
109 |
level = 0
|
110 |
index = indexes[0]
|
111 |
while index.parent().isValid():
|
112 |
index = index.parent() |
113 |
level += 1
|
114 |
if sym is not None: |
115 |
menu = QMenu() |
116 |
if advanced:
|
117 |
editSymbolAction = QAction(self.tr("Edit Symbol")) |
118 |
editSymbolAction.triggered.connect(lambda: self.editSymbolActionClickEvent(item, 0)) |
119 |
menu.addAction(editSymbolAction) |
120 |
editDisplaySymbolAction = QAction(self.tr("Edit Symbol for Display")) |
121 |
editDisplaySymbolAction.triggered.connect(lambda: self.editDisplaySymbolActionClickEvent(item, 0)) |
122 |
menu.addAction(editDisplaySymbolAction) |
123 |
displaySymbolAction = QAction(self.tr("Display Symbol")) |
124 |
displaySymbolAction.triggered.connect(lambda: self.displaySymbolActionClickEvent(item, 0)) |
125 |
menu.addAction(displaySymbolAction) |
126 |
if advanced:
|
127 |
deleteSymbolAction = QAction(self.tr("Delete Symbol")) |
128 |
deleteSymbolAction.triggered.connect(lambda: self.deleteSymbolActionClickEvent(sym.getType(), text)) |
129 |
menu.addAction(deleteSymbolAction) |
130 |
menu.exec_(self.viewport().mapToGlobal(position))
|
131 |
else:
|
132 |
if advanced:
|
133 |
menu = QMenu() |
134 |
editAttrAction = QAction(self.tr("Edit Attribute")) |
135 |
editAttrAction.triggered.connect(lambda: self.onEditAttrClicked(item, 0)) |
136 |
menu.addAction(editAttrAction) |
137 |
|
138 |
configs = app_doc_data.getConfigs('Project', 'Operation Code') |
139 |
code = configs[0].value if 1 == len(configs) else '' |
140 |
if code == 'nK6uurpuiw==': # Samsung |
141 |
spaceAttrAction = QAction(self.tr("================")) |
142 |
menu.addAction(spaceAttrAction) |
143 |
deleteAttrAction = QAction(self.tr("Delete Unused Symbols")) |
144 |
deleteAttrAction.triggered.connect(lambda: self.onDeleteSymbolBatchByCategory(item)) |
145 |
menu.addAction(deleteAttrAction) |
146 |
|
147 |
resetDefaultScaleAction = QAction(self.tr("Reset All Default Symbol Scale")) |
148 |
resetDefaultScaleAction.triggered.connect(self.resetDefaultScale)
|
149 |
menu.addAction(resetDefaultScaleAction) |
150 |
|
151 |
menu.exec_(self.viewport().mapToGlobal(position))
|
152 |
|
153 |
def resetDefaultScale(self): |
154 |
text, result = QInputDialog.getText(self, self.tr('Reset all default symbol scale'), self.tr('To proceed, enter "Confirm" in the input box below.')) |
155 |
|
156 |
if result and text == 'Confirm': |
157 |
app_doc_data = AppDocData.instance() |
158 |
|
159 |
for sym in self.symbols: |
160 |
sym.setScale() |
161 |
app_doc_data.updateSymbol(sym) |
162 |
|
163 |
self.initSymbolTreeView()
|
164 |
|
165 |
QMessageBox.information(self, self.tr('Information'), self.tr('Succeeded')) |
166 |
|
167 |
def editSymbolActionClickEvent(self, item, columNo): |
168 |
self.showSymbolEditorDialog(item, columNo)
|
169 |
|
170 |
def editDisplaySymbolActionClickEvent(self, item, columNo): |
171 |
self.showSymbolEditorDialog(item, columNo, True) |
172 |
|
173 |
def onDeleteSymbolBatchByCategory(self, item): |
174 |
"""Delete unused symbol by category"""
|
175 |
msg = QMessageBox() |
176 |
msg.setIcon(QMessageBox.Critical) |
177 |
msg.setText(self.tr('Are you sure you want to delete symbols in this category?\nData can not be restored!')) |
178 |
msg.setWindowTitle(self.tr('Delete symbols')) |
179 |
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) |
180 |
result = msg.exec_() |
181 |
self.handleDeleteSymbolBatchAction(result, item)
|
182 |
|
183 |
def handleDeleteSymbolBatchAction(self, result, item): |
184 |
if result == QMessageBox.Ok:
|
185 |
text, result = QInputDialog.getText(self, self.tr('Delete symbols'), self.tr('To proceed, enter "Confirm" in the input box below.')) |
186 |
|
187 |
if result and text == 'Confirm': |
188 |
app_doc_data = AppDocData.instance() |
189 |
project = app_doc_data.getCurrentProject() |
190 |
|
191 |
data = item.data(self.TREE_DATA_ROLE)
|
192 |
itemType = data[2]
|
193 |
|
194 |
unusedSymbols = app_doc_data.getSymbolNameListByUnused() |
195 |
unusedUIDs = [symbol[0] for symbol in unusedSymbols] |
196 |
categorySymbols = app_doc_data.getSymbolListByType('type', itemType)
|
197 |
itemNames = [symbol.sName for symbol in categorySymbols if symbol.uid in unusedUIDs] |
198 |
|
199 |
for itemName in itemNames: |
200 |
res, _ = app_doc_data.deleteSymbol(itemName) |
201 |
if res:
|
202 |
imagePath = os.path.join(project.getImageFilePath(), itemType, |
203 |
itemName + '.png') # itemName DOESN'T includes ".png" |
204 |
imageDisplayPath = os.path.join(project.getImageFilePath(), itemType, |
205 |
itemName + '_display' + '.png') # itemName DOESN'T includes ".png" |
206 |
if os.path.exists(imagePath):
|
207 |
os.remove(imagePath) |
208 |
if os.path.exists(imageDisplayPath):
|
209 |
os.remove(imageDisplayPath) |
210 |
|
211 |
svgPath = os.path.join(project.getSvgFilePath(), itemType, itemName + '.svg')
|
212 |
if os.path.exists(svgPath):
|
213 |
os.remove(svgPath) |
214 |
else:
|
215 |
pass
|
216 |
|
217 |
self.initSymbolTreeView()
|
218 |
|
219 |
|
220 |
def onEditAttrClicked(self, item, columnNo): |
221 |
"""pop up attribute editor dialog"""
|
222 |
from SymbolAttrEditorDialog import QSymbolAttrEditorDialog |
223 |
|
224 |
try:
|
225 |
data = item.data(self.TREE_DATA_ROLE)
|
226 |
|
227 |
dlg = QSymbolAttrEditorDialog(self, data)
|
228 |
dlg.show() |
229 |
dlg.exec_() |
230 |
except Exception as ex: |
231 |
from App import App |
232 |
|
233 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
234 |
f"{sys.exc_info()[-1].tb_lineno}"
|
235 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
236 |
|
237 |
def displaySymbolActionClickEvent(self, item, columnNo): |
238 |
# project = AppDocData.instance().getCurrentProject()
|
239 |
# image = QImage(os.path.join(project.getImageFilePath(), itemType, itemName, "PNG")) #itemName includes ".png"
|
240 |
try:
|
241 |
sym = self.getSymbolByItemName(item, columnNo)
|
242 |
if sym is not None: |
243 |
# origin symbol image
|
244 |
path = sym.getPath() |
245 |
image = QImage(path, "PNG")
|
246 |
# symbol image for display
|
247 |
path = os.path.splitext(path) |
248 |
path = path[0] + '_display' + path[1] |
249 |
image2 = QImage(path, "PNG") if os.path.exists(path) else None |
250 |
dialog = QSymbolDisplayDialog.QSymbolDisplayDialog(image, image2) |
251 |
dialog.showDialog() |
252 |
else:
|
253 |
QMessageBox.about(self, self.tr('Error'), self.tr('Error occurs during loading symbol data.')) |
254 |
except Exception as ex: |
255 |
from App import App |
256 |
from AppDocData import MessageType |
257 |
|
258 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
259 |
sys.exc_info()[-1].tb_lineno)
|
260 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
261 |
|
262 |
def deleteSymbolActionClickEvent(self, itemType, itemName): |
263 |
msg = QMessageBox() |
264 |
msg.setIcon(QMessageBox.Critical) |
265 |
msg.setText(self.tr('Are you sure you want to delete selected symbol?\nData can not be restored!')) |
266 |
msg.setWindowTitle(self.tr('Delete symbol')) |
267 |
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) |
268 |
result = msg.exec_() |
269 |
self.handleDeleteSymbolAction(result, itemType, itemName)
|
270 |
|
271 |
'''
|
272 |
@history 2018.05.03 Jeongwoo Modify file path with ".png" and ".svg"
|
273 |
Use project object when making svgPath
|
274 |
'''
|
275 |
def handleDeleteSymbolAction(self, result, itemType, itemName): |
276 |
if result == QMessageBox.Ok:
|
277 |
res, _ = AppDocData.instance().deleteSymbol(itemName) |
278 |
if res:
|
279 |
project = AppDocData.instance().getCurrentProject() |
280 |
imagePath = os.path.join(project.getImageFilePath(), itemType, |
281 |
itemName + '.png') # itemName DOESN'T includes ".png" |
282 |
imageDisplayPath = os.path.join(project.getImageFilePath(), itemType, |
283 |
itemName + '_display' + '.png') # itemName DOESN'T includes ".png" |
284 |
if os.path.exists(imagePath):
|
285 |
os.remove(imagePath) |
286 |
if os.path.exists(imageDisplayPath):
|
287 |
os.remove(imageDisplayPath) |
288 |
|
289 |
svgPath = os.path.join(project.getSvgFilePath(), itemType, itemName + '.svg')
|
290 |
if os.path.exists(svgPath):
|
291 |
os.remove(svgPath) |
292 |
|
293 |
self.initSymbolTreeView()
|
294 |
else:
|
295 |
pass
|
296 |
|
297 |
def initSymbolTreeView(self): |
298 |
"""initialize symbol tree view"""
|
299 |
project = AppDocData.instance().getCurrentProject() |
300 |
if project is not None: |
301 |
if self.model(): |
302 |
self.model().clear()
|
303 |
projectPath = project.getPath().replace("\\", "/") |
304 |
self.load_symbol_info()
|
305 |
self.expandAll()
|
306 |
|
307 |
self.selectionModel().selectionChanged.connect(self.on_selection_changed) |
308 |
|
309 |
def load_symbol_info(self): |
310 |
"""load symbol information and display it on tree view"""
|
311 |
try:
|
312 |
app_doc_data = AppDocData.instance() |
313 |
|
314 |
model = QStandardItemModel() |
315 |
symbolTypeList = app_doc_data.getSymbolTypeList() |
316 |
for row, symbolType in enumerate(symbolTypeList): |
317 |
item = QStandardItem(symbolType[2])
|
318 |
item.setData(symbolType, self.TREE_DATA_ROLE)
|
319 |
item.setEditable(False)
|
320 |
item.setSelectable(False)
|
321 |
|
322 |
symbolList = app_doc_data.getSymbolListByType('UID', symbolType[0]) |
323 |
for symbol in symbolList: |
324 |
child = QStandardItem(symbol.getName()) |
325 |
child.setData(symbol, self.TREE_DATA_ROLE)
|
326 |
child.setEditable(False)
|
327 |
|
328 |
_, svg = app_doc_data.read_symbol_shape(symbol.sName) |
329 |
if svg:
|
330 |
symbol.pixmap = QPixmap() |
331 |
symbol.pixmap.loadFromData(svg if isinstance(svg, bytes) else svg.encode()) |
332 |
icon = QIcon(symbol.pixmap) |
333 |
child.setIcon(icon) |
334 |
child.svgFilePath = None # save svg file path |
335 |
else:
|
336 |
svgPath = symbol.getSvgFileFullPath() |
337 |
symbol.pixmap = QPixmap(svgPath) |
338 |
icon = QIcon(symbol.pixmap) |
339 |
child.setIcon(icon) |
340 |
child.svgFilePath = svgPath # save svg file path
|
341 |
|
342 |
item.appendRow(child) |
343 |
|
344 |
item.sortChildren(0, Qt.AscendingOrder)
|
345 |
model.appendRow(item) |
346 |
|
347 |
proxy_model = SearchProxyModel() |
348 |
proxy_model.setSourceModel(model) |
349 |
proxy_model.setDynamicSortFilter(True)
|
350 |
proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) |
351 |
self.setModel(proxy_model)
|
352 |
|
353 |
"""
|
354 |
symbolTypeList = app_doc_data.getSymbolTypeList()
|
355 |
for symbolType in symbolTypeList:
|
356 |
if not symbolType[1]: continue # skip if category is empty
|
357 |
parent = QTreeWidgetItem(self, [symbolType[2]])
|
358 |
parent.setData(0, self.TREE_DATA_ROLE, symbolType)
|
359 |
symbolList = app_doc_data.getSymbolListByType('UID', symbolType[0])
|
360 |
for symbol in symbolList:
|
361 |
symbolItem = QTreeWidgetItem(parent, [symbol.getName()])
|
362 |
symbolItem.setData(0, self.TREE_DATA_ROLE, symbol)
|
363 |
|
364 |
_, svg = app_doc_data.read_symbol_shape(symbol.sName)
|
365 |
if svg:
|
366 |
symbol.pixmap = QPixmap()
|
367 |
symbol.pixmap.loadFromData(svg if isinstance(svg, bytes) else svg.encode())
|
368 |
icon = QIcon(symbol.pixmap)
|
369 |
symbolItem.setIcon(0, icon)
|
370 |
symbolItem.svgFilePath = None # save svg file path
|
371 |
else:
|
372 |
svgPath = symbol.getSvgFileFullPath()
|
373 |
symbol.pixmap = QPixmap(svgPath)
|
374 |
icon = QIcon(symbol.pixmap)
|
375 |
symbolItem.setIcon(0, icon)
|
376 |
symbolItem.svgFilePath = svgPath # save svg file path
|
377 |
|
378 |
parent.sortChildren(0, Qt.AscendingOrder)
|
379 |
"""
|
380 |
except Exception as ex: |
381 |
from App import App |
382 |
|
383 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
384 |
sys.exc_info()[-1].tb_lineno)
|
385 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
386 |
|
387 |
def showSymbolEditorDialog(self, item, columnNo, display=False): |
388 |
"""pop up symbol editor dialog"""
|
389 |
|
390 |
try:
|
391 |
sym = self.getSymbolByItemName(item, columnNo)
|
392 |
if sym and display: |
393 |
# for symbol image for display
|
394 |
path = os.path.splitext(sym.getPath()) |
395 |
path = path[0] + '_display' + path[1] |
396 |
if os.path.exists(path):
|
397 |
image = QImage(path, "PNG")
|
398 |
else:
|
399 |
path = sym.getPath() |
400 |
image = QImage(path, "PNG")
|
401 |
symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image,
|
402 |
AppDocData.instance().getCurrentProject(), |
403 |
sym, True)
|
404 |
(isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
405 |
if isAccepted:
|
406 |
self.initSymbolTreeView()
|
407 |
elif sym:
|
408 |
# for symbol data and detection image
|
409 |
path = sym.getPath() |
410 |
image = QImage(path, "PNG")
|
411 |
symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image,
|
412 |
AppDocData.instance().getCurrentProject(), |
413 |
sym, False)
|
414 |
(isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
415 |
if isAccepted:
|
416 |
self.initSymbolTreeView()
|
417 |
else:
|
418 |
QMessageBox.about(self, self.tr('Error'), self.tr('Error occurs during loading symbol data.')) |
419 |
except Exception as ex: |
420 |
from App import App |
421 |
from AppDocData import MessageType |
422 |
|
423 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
424 |
sys.exc_info()[-1].tb_lineno)
|
425 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
426 |
|
427 |
def select_symbol(self, symbol): |
428 |
''' no more used '''
|
429 |
"""select a tree with given symbol"""
|
430 |
|
431 |
founds = self.findItems(symbol.name, Qt.MatchExactly | Qt.MatchRecursive, 0) |
432 |
if founds:
|
433 |
self.setCurrentItem(founds[0]) |
434 |
|
435 |
def itemDoubleClickEvent(self, index): |
436 |
"""pop up symbol editor"""
|
437 |
item = self.model().sourceModel().itemFromIndex(self.model().mapToSource(index)) |
438 |
if item:
|
439 |
data = item.data(Qt.UserRole) |
440 |
if data and type(data) is SymbolBase.SymbolBase: |
441 |
sym = self.getSymbolByItemName(item, 0) |
442 |
itemName = item.text() |
443 |
if sym is not None: |
444 |
self.showSymbolEditorDialog(item, 0) |
445 |
|
446 |
def getSymbolByItemName(self, item, columnNo): |
447 |
"""Get Symbol data by symbol name"""
|
448 |
name = item.text() |
449 |
sym = AppDocData.instance().getSymbolByQuery("name", name)
|
450 |
|
451 |
return sym
|
452 |
|
453 |
def on_selection_changed(self, new_selection, old_selection): |
454 |
"""show symbol's property when selection changed"""
|
455 |
|
456 |
if new_selection.indexes():
|
457 |
proxy_model = self.model()
|
458 |
item = proxy_model.sourceModel().itemFromIndex(proxy_model.mapToSource(new_selection.indexes()[0]))
|
459 |
if item is not None: |
460 |
data = item.data(self.TREE_DATA_ROLE)
|
461 |
if data is not None and type(data) is symbol.SymbolBase: |
462 |
self.singleClicked.emit(data)
|
463 |
|
464 |
def onCurrentItemChanged(self, current, previous): |
465 |
"""show symbol's property when selection changed"""
|
466 |
item = self.currentItem()
|
467 |
if item is not None: |
468 |
data = item.data(0, self.TREE_DATA_ROLE) |
469 |
if data is not None and type(data) is symbol.SymbolBase: |
470 |
self.singleClicked.emit(data)
|
471 |
|
472 |
def startDrag(self, dropAction): |
473 |
"""start drag"""
|
474 |
try:
|
475 |
index = self.currentIndex()
|
476 |
proxy_model = self.model()
|
477 |
items = [proxy_model.sourceModel().itemFromIndex(proxy_model.mapToSource(index))] |
478 |
if items and hasattr(items[0], 'svgFilePath') and os.path.exists(items[0].svgFilePath): |
479 |
symData = items[0].data(self.TREE_DATA_ROLE) |
480 |
|
481 |
mime = QMimeData() |
482 |
mime.setText(symData.getName()) |
483 |
mime.tag = symData |
484 |
|
485 |
drag = QDrag(self)
|
486 |
drag.setMimeData(mime) |
487 |
originalPoint = symData.getOriginalPoint() if not symData.getConvertingPoint() else symData.getConvertingPoint() |
488 |
drag.setHotSpot(QPoint(int(float(originalPoint.split(",")[0])), int(float(originalPoint.split(",")[1])))) |
489 |
pix = QPixmap(symData.pixmap.size()) |
490 |
pix.fill(Qt.transparent) |
491 |
painter = QPainter(pix) |
492 |
painter.setOpacity(0.3)
|
493 |
painter.drawPixmap(QPoint(), symData.pixmap) |
494 |
painter.end() |
495 |
drag.setPixmap(pix) |
496 |
drag.exec(Qt.CopyAction) |
497 |
except Exception as ex: |
498 |
from App import App |
499 |
|
500 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
501 |
sys.exc_info()[-1].tb_lineno)
|
502 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |