0

I have a simple example here. What I want to happen is when a user changes the toggle state of the 'Checkbox' i want it to set the property value for the CustomTreeWidgetItem's attr.

In this case each CustomTreeWidgetItem has an attr called dataObject which is where I store my class object Family. Family has an attribute enabled which I want this property to reflect the toggle state of the TreeWidgetItems' checkbox.

I have looked around online and have not found a solution yet for this. Most answers were in c++ or they were causing errors. You can test the results by clicking the print button. It should reflect the changes.

Here are the highlighted bits.

Updated: The linked question does not answer my question. It does not return the value for the checkbox clicked.

What is this code doing in simple terms? And what do i need to modify to make it set the data object to True or False? Currently it returns 0 or 2. I'm not sure if that is tristate or what. Hope someone can explain what is going on.

if column == 0 and role == 10:

My custom tree widget items have the property dataObject. This is where I store my class object Family which has the property enabled in it.

self.dataObject = None

class Family:
    def __init__(self, name, members=None, data=None):
        self.name = name
        self.enabled = True

Hope that helps.

Thanks

enter image description here

all the code

# Imports
# ------------------------------------------------------------------------------
import sys
from PySide import QtGui, QtCore

# Class
# ------------------------------------------------------------------------------
class Family:
    def __init__(self, name, members=None, data=None):
        self.name = name
        self.enabled = True


# Custom Tree Widget
# ------------------------------------------------------------------------------
class TreeNodeItem( QtGui.QTreeWidgetItem ):

    def __init__( self, parent, name ):

        ## Init super class ( QtGui.QTreeWidgetItem )
        super( TreeNodeItem, self ).__init__( parent )

        # Column 0 - Text:
        self.setText( 0, name )

        # Tree Node Data
        self.dataObject = None

    def setData(self, column, role, value):
        if column == 0 and role == 10:
            self.dataObject.enabled = value

        super(TreeNodeItem, self).setData(column, role, value)


# Variables
# ------------------------------------------------------------------------------
Families = [
    Family("Smith"), 
    Family("Michaels"),
    Family("Wislon"), 
    Family("Yoder")
]

# Main
# ------------------------------------------------------------------------------
class Example(QtGui.QWidget):

    def __init__(self,):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):

        # formatting
        self.resize(400, 400)
        self.setWindowTitle("Example")

        # widgets
        self.printData = QtGui.QPushButton("Print Families Data")
        self.itemList = QtGui.QTreeWidget()
        self.itemList.setItemsExpandable(True)
        self.itemList.setAnimated(True)
        self.itemList.setItemsExpandable(True)
        self.itemList.setColumnCount(1)
        self.itemList.setHeaderLabels(['Families'])

        # signals
        self.printData.clicked.connect(self.PrintAllData)

        # layout - row/column/verticalpan/horizontalspan
        self.mainLayout = QtGui.QGridLayout(self)
        self.mainLayout.addWidget(self.itemList,0,0)
        self.mainLayout.addWidget(self.printData,1,0)

        self.center()
        self.show()
        self.UpdateFamilies()

    def center(self):

        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def PrintAllData(self):
        for f in Families:
            print f.name, f.enabled

    def UpdateFamilies(self):
        treeWidget = self.itemList
        treeWidget.clear()

        for f in Families:
            # Add Families
            treeNode = TreeNodeItem(treeWidget, f.name)
            # assign family class object to dataObject attr of treenode
            treeNode.dataObject = f
            treeNode.setCheckState(0, QtCore.Qt.Checked)

# Main
# ------------------------------------------------------------------------------
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
JokerMartini
  • 5,674
  • 9
  • 83
  • 193

1 Answers1

1

The answer was in the linked question (although in C++) Is it possible to create a signal for when a QTreeWidgetItem checkbox is toggled?

Short answer - no, there doesn't appear to be a signal for that checkbox. There are 2 ways to fix this:

1) As in the linked question, you could implement the SetData method and update your data at the same time:

# Custom Tree Widget
# ------------------------------------------------------------------------------
class TreeNodeItem( QtGui.QTreeWidgetItem ):

    def __init__( self, parent, name ):

        ## Init super class ( QtGui.QTreeWidgetItem )
        super( TreeNodeItem, self ).__init__( parent )

        # Column 0 - Text:
        self.setText( 0, name )

        # Tree Node Data
        self.dataObject = None

    def setData(self, column, role, value):
        if column == 0 and role == 10:
            self.dataObject.enabled = value

        super(TreeNodeItem, self).setData(column, role, value)

2) You could also try manually creating a checkbox, connect up it's signal and add it to the TreeNodeItem using QTreeWidget.setItemWidgem

Community
  • 1
  • 1
FrozenKiwi
  • 1,362
  • 13
  • 26
  • How do I fire the set data when the check box is changed? – JokerMartini Nov 14 '15 at 15:54
  • 1
    why does the value result in 0 or 2? and what does this line 'if column == 0 and role == 10:' mean in simple terms? – JokerMartini Nov 14 '15 at 21:00
  • You don't 'fire' the setValue, the setValue is called by QT when the user changes values in the tree cells. In this case, you override the default implementation, and when the value with the role of CheckState changes, (http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum) pipe the value being set into your dataObject – FrozenKiwi Nov 15 '15 at 02:11
  • @JokerMartini 0 stands for `Qt::Unchecked`, 2 stands for `Qt::Checked`. `role == 10` means `Qt::CheckStateRole`. `column == 0` means the first column of the QTreeWidget is triggered – oscarz Jun 02 '20 at 23:22