PyQt Tree Widget, adding check boxes for dynamic removal

北城以北 提交于 2019-11-30 03:01:23
Andy

In addition to the answer you provided, you can simplify your logic by using the ItemIsTristate flag on the parent elements.

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import sys

def main(): 
    app     = QApplication (sys.argv)
    tree    = QTreeWidget ()
    headerItem  = QTreeWidgetItem()
    item    = QTreeWidgetItem()

    for i in xrange(3):
        parent = QTreeWidgetItem(tree)
        parent.setText(0, "Parent {}".format(i))
        parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        for x in xrange(5):
            child = QTreeWidgetItem(parent)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setText(0, "Child {}".format(x))
            child.setCheckState(0, Qt.Unchecked)
    tree.show() 
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

The three most important lines of code are:

parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)

This one sets up the parent element to be a three state check box.

child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setCheckState(0, Qt.Unchecked)

These set up the child to be selectable and set the default to unchecked. If the child's checkbox isn't given a state, the checkbox element does not appear.


The code above builds a very simple tree.

However, if I check a check box on the parent element, all the children are automatically selected:

If, I wish to unselect a single child, the parent enters the partially selected (Tri-State):

If all children are unselected, the parent is automatically unselected. If the parent is unselected, all children are automatically unselected as well.

sudobangbang

QTreeWidgetItem actually has a built in check box that you can use fairly easily.

For example:

item = QTreeWidgetItem(self.treeWidget)

item.setCheckState(0, QtCore.Qt.Unchecked)

This is not an answer to your question, rather how to use the checkboxes once you have them. I used the example above from the answer marked as correct. It worked, but then when I tried to find how to know which checkboxes were marked, and I had a lot of issues. After a lot of searching I found a solution that worked for me, as I see there is no a lot of doc, so I want to leave a record for the future. Just to mention I used several solutions as invisibleRootItem in order to find the children of the parent but that didn't work.

I ended up using the class QTreeWidgetItemIterator with a flag QtGui.QTreeWidgetItemIterator.Checked in order to retreive the text of the checkboxes marked, and with that, I can continue working.

def vrfs_selected(self):
    iterator = QtGui.QTreeWidgetItemIterator(self.tree, QtGui.QTreeWidgetItemIterator.Checked)
    while iterator.value():
        item = iterator.value()
        print (item.text(0))    
        iterator += 1

the link to the documentation http://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/PyQt-x11-gpl-4.7.2/doc/html/qtreewidgetitemiterator.html and an example https://riverbankcomputing.com/pipermail/pyqt/2014-May/034315.html

I ported @andy's awesome example to PyQt5:

from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.Qt import Qt
import sys

def main(): 
    app     = QtWidgets.QApplication(sys.argv)
    tree    = QtWidgets.QTreeWidget()
    headerItem  = QtWidgets.QTreeWidgetItem()
    item    = QtWidgets.QTreeWidgetItem()

    for i in range(3):
        parent = QtWidgets.QTreeWidgetItem(tree)
        parent.setText(0, "Parent {}".format(i))
        parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        for x in range(5):
            child = QtWidgets.QTreeWidgetItem(parent)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setText(0, "Child {}".format(x))
            child.setCheckState(0, Qt.Unchecked)
    tree.show() 
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!