2017-10-05 15 views
1

J'implémente un logiciel d'analyse gui qui utilise un QTreeWidget avec deux classes TreeWidgetItem personnalisées. Chaque élément dans l'arbre est responsable plus ou moins de sa propre tenue de livres en gardant la trace des ensembles de données et des objets qui y sont attachés. J'aimerais pouvoir émettre un signal à l'intérieur des fonctions du Custom QTreeWidgetItems, mais le code suivant génère une erreur indiquant que myTWItem ne peut pas être converti en QObject. Est-il possible d'émettre un signal à partir d'un QTreeWidgetItem de cette manière?alternatives pour émettre un signal d'une sous-classe 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_()) 

sorties:

>>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 

Répondre

1

Une façon de le faire serait de définir les signaux personnalisés sur le widget arbre parent. Puis, de l'article, vous seriez en mesure de le faire:

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

Bien sûr, l'inconvénient évident ici, est que cela ne fonctionnera pas pour les articles qui n'ont pas encore été ajoutés à un arbre (bien que, dans certains cas, cela pourrait être un avantage). Une autre méthode consiste à créer une classe de signaux distincte qui hérite de QObject. Pour garder les choses légères, il serait préférable d'utiliser une instance partagée de ceci, en créant plutôt un pour chaque élément. Cela permettrait également d'éviter d'avoir à établir des connexions pour chaque élément dans l'arborescence:

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_()) 

(NB: bien sûr, de faire les choses dans l'une de ces deux façons signifie que sender() ne reviendra pas ce que vous auriez normalement Attendez-vous à).