【问题标题】:Pyqt5 QTreeWIdgetItem with select one item checkbox at atimePyqt5 QTreeWIdgetItem,一次选择一个项目复选框
【发布时间】:2022-10-14 00:31:09
【问题描述】:

我有一个 QTreeWidget,每个 QTreeWidgetItem 都有 3 个复选框。我想做两件事,但我不知道该怎么做。

  1. 用户一次只能选择一个复选框 每个 QTreeWidgetItem.So 选择一个给定的复选框 QTreeWidgetItem 应该取消选择其他复选框 QTreeWidgetItem。
  2. 给定父 QTreeWidgetItem 复选框的选择/取消选择 应该选择/取消选择同一列中的所有子复选框。 下面是我的代码:

    任何帮助将不胜感激

    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()
        tree.resize(500, 200)
        headerItem  = QtWidgets.QTreeWidgetItem()
        item    = QtWidgets.QTreeWidgetItem()
        tree .setColumnCount(4)
        tree .setHeaderLabels(["pluto", "X", "Y", "Z", ""])
        for i in range(3):
            parent = QtWidgets.QTreeWidgetItem(tree)
            parent.setText(0, "Parent {}".format(i))
            parent.setCheckState(1, Qt.Unchecked)
            parent.setCheckState(2, Qt.Unchecked)
            parent.setCheckState(3, Qt.Unchecked)
            #parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
            for x in range(5):
                child = QtWidgets.QTreeWidgetItem(parent)
                child.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
                child.setText(0, "Child {}".format(x))
                child.setCheckState(1, Qt.Unchecked)
                child.setCheckState(2, Qt.Unchecked)
                child.setCheckState(3, Qt.Unchecked)
    
    
        tree.show()
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    

【问题讨论】:

  • 好吧,您可以先连接到itemChanged 信号来同时执行这两项操作:只要项目/列的checkState()Checked,您只需执行任何操作,然后继续取消选中其他兄弟姐妹并检查孩子在该列:这将自动为所有子元素和孙子元素触发相同的操作。
  • 我尝试过执行类似 child.itemChanged.connect(self.boxSelected) 的操作,但出现错误:“AttributeError: 'QTreeWidgetItem' object has no attribute 'itemChanged'”
  • 为什么要连接到该项目?除了物品是不是QObjects(所以它们没有信号),您应该连接到表格小部件的信号。
  • 我已经尝试过 ItemChanged 和 ItemClicked 但它们都只能正确检测到 qtreeWidgetItem 的选择而不是复选框。因此,如果我单击一个项目,然后单击另一个项目的复选框,则 currentItem 始终是我单击的那个而不是我选择的复选框

标签: python pyqt5 qtreewidget qtreewidgetitem


【解决方案1】:

我已经通过使用 itemClicked 解决了我自己的问题。如果有人感兴趣,这是我的解决方案。

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

class treeManagement:
    def __init__(self):
        app     = QtWidgets.QApplication(sys.argv)
        self.tree    = QtWidgets.QTreeWidget()
        self.tree.resize(500, 200)
        headerItem  = QtWidgets.QTreeWidgetItem()
        item    = QtWidgets.QTreeWidgetItem()
        self.tree .setColumnCount(4)
        self.tree .setHeaderLabels(["pluto", "X", "Y", "Z", ""])
        for i in range(3):
            parent = QtWidgets.QTreeWidgetItem(self.tree)
            parent.setText(0, "Parent {}".format(i))
            parent.setCheckState(1, Qt.Unchecked)
            parent.setCheckState(2, Qt.Unchecked)
            parent.setCheckState(3, Qt.Unchecked)

            for x in range(5):
                child = QtWidgets.QTreeWidgetItem(parent)
                child.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
                child.setText(0, "Child {}".format(x))
                child.setCheckState(1, Qt.Unchecked)
                child.setCheckState(2, Qt.Unchecked)
                child.setCheckState(3, Qt.Unchecked)

        self.tree.itemClicked.connect(self.checkboxSelectionChanged)
        self.tree.show()
        sys.exit(app.exec_())

    def checkboxSelectionChanged(self,selectedItem, selectedColumn):
        print(selectedItem.text(0))
        print(selectedColumn)
        # In this method I manage checkbox selected

        if selectedItem is None:
            return


        # 0-The item is unchecked.
        # 1-The item is partially checked. Items in hierarchical models may be partially checked if some, but not all,
        # of their children are checked.
        # 2-The item is checked.

        sumCheckState=selectedItem.checkState(1)+selectedItem.checkState(2)+selectedItem.checkState(3)

        state = QtCore.Qt.Unchecked
        for i in range(1, 4):
            if selectedColumn != i:
                if sumCheckState>=4:#Prevent update if user clicked in the space near checkbox or there's only one
                    # checkbox currently checked in this row
                    selectedItem.setCheckState(i, QtCore.Qt.Unchecked)
            elif selectedItem.childCount() > 0:  # selectedColumn=i
                for j in range(selectedItem.childCount()):
                    child = selectedItem.child(j)
                    for k in range(1, 4):
                        if selectedColumn != k:
                            if sumCheckState >= 4 or (sumCheckState==2 and child.checkState(k)== QtCore.Qt.Checked) :
                                # Prevent update if user clicked in the space near checkbox or there's only one
                               # checkbox currently checked in this row
                              child.setCheckState(k, QtCore.Qt.Unchecked)
                        else:
                               child.setCheckState(k, selectedItem.checkState(selectedColumn))
            elif selectedItem.parent() is not None:
                # I have clicked on a child element so no parent should be in checked state
                if sumCheckState >= 4:#Prevent update if user clicked in the space near checkbox or there's only one
                    # checkbox currently checked in this row
                    for i in range(1, 4):
                        selectedItem.parent().setCheckState(i, QtCore.Qt.Unchecked)

if __name__ == '__main__':
    t=treeManagement()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多