从 QTreeWidgetItem 子类 PyQt/PySide 发出信号的替代方法
Posted
技术标签:
【中文标题】从 QTreeWidgetItem 子类 PyQt/PySide 发出信号的替代方法【英文标题】:alternatives to emit a signal from a QTreeWidgetItem SubClass PyQt/PySide 【发布时间】:2018-03-17 11:51:19 【问题描述】:我正在实现一个使用 QTreeWidget 和几个自定义 TreeWidgetItem 类的 gui 分析软件。树中的每个项目或多或少地负责自己的簿记,以跟踪附加到它的数据集和对象。我希望能够从自定义 QTreeWidgetItems 的函数中发出信号,但以下代码会导致无法将 myTWItem 转换为 QObject 的错误。有没有办法以这种方式从 QTreeWidgetItem 发出信号?
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()
不会返回您通常期望的结果)。
【讨论】:
以上是关于从 QTreeWidgetItem 子类 PyQt/PySide 发出信号的替代方法的主要内容,如果未能解决你的问题,请参考以下文章
如何将 itemExpanded 与 QTreeWidgetItem 的子类一起使用