2017-10-05 118 views
1

我正在實現一個gui分析軟件,它使用QTreeWidget和一些自定義的TreeWidgetItem類。樹中的每個項目或多或少都對其自己的記錄負責,以跟蹤附加到其上的數據集和對象。我希望能夠從自定義QTreeWidgetItems的函數內發出信號,但以下代碼導致myTWItem無法轉換爲QObject的錯誤。有沒有辦法以這種方式從QTreeWidgetItem發出信號?替代品從QTreeWidgetItem發射信號子類PyQt/PySide

import sys 
from PyQt5 import QtCore, QtWidgets, QtGui 


class myTWItem(QtWidgets.QTreeWidgetItem): 
    childAdded = QtCore.pyqtSignal(object) 

    def addChild(self, child): 
     super(myTWItem, self).addChild(child) 
     self.childAdded.emit(child) 

app = QtWidgets.QApplication(sys.argv) 
tw = QtWidgets.QTreeWidget() 

item = myTWItem() 

tw.addTopLevelItem(item) 
item.setText(0, "James") 

child = QtWidgets.QTreeWidgetItem() 
child.setText(0, "Braddock") 
item.addChild(child) 

tw.show() 
sys.exit(app.exec_()) 

輸出:要做到這一點

>>Traceback (most recent call last): 
>> File "C:/Coding/Python/dataquick/sandbox/treewidgettest.py", line 22, in <module> 
>> item.addChild(child) 
>> File "C:/Coding/Python/dataquick/sandbox/treewidgettest.py", line 10, in addChild 
>> self.childAdded.emit(child) 
>>TypeError: myTWItem cannot be converted to PyQt5.QtCore.QObject in this context 
>> 
>>Process finished with exit code 1 

回答

1

的一種方法是定義父樹插件的定製信號。然後,從項目,你就能夠做到:

tree = self.treeWidget() 
if tree is not None: 
    tree.childAdded.emit(child) 

當然,這裏的明顯缺點是,這不會對尚未被添加到樹中的項目工作(雖然,在某些情況下,這可能是一個優勢)。

另一種方法是創建一個單獨的信號類繼承QObject。爲了保持輕量級,最好使用這個共享實例,而不是爲每個項目創建一個實例。這也將避免進行連接,爲樹中的每個項目:

import sys 
from PyQt5 import QtCore, QtWidgets, QtGui 

class TWSignals(QtCore.QObject): 
    childAdded = QtCore.pyqtSignal(object) 

class myTWItem(QtWidgets.QTreeWidgetItem): 
    signals = TWSignals() 

    def addChild(self, child): 
     super(myTWItem, self).addChild(child) 
     self.signals.childAdded.emit(child) 

app = QtWidgets.QApplication(sys.argv) 
tw = QtWidgets.QTreeWidget() 

# connect using the class attribute 
myTWItem.signals.childAdded.connect(
    lambda item: print('child added:', item.text(0))) 

item = myTWItem() 

tw.addTopLevelItem(item) 
item.setText(0, "James") 

child = QtWidgets.QTreeWidgetItem() 
child.setText(0, "Braddock") 
item.addChild(child) 

tw.show() 
sys.exit(app.exec_()) 

(注:當然,在使用這兩種方式做事意味着sender()不會回到你通常會期待它)。