You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5 QTreeWidgetItem复选框单选项及父子同步功能实现求助

QTreeWidget复选框功能实现方案

要实现你需求的两个功能,核心是通过监听QTreeWidget的itemChanged信号,在信号处理函数中完成逻辑控制,以下是具体实现方案:

功能1:单个Item仅保留一个选中的复选框

当某Item的任意一列(X/Y/Z列,对应索引1/2/3)复选框被选中时,自动将该Item的另外两列复选框设为未选中状态。为了避免修改状态时重复触发信号,需要用一个标志位临时阻断信号循环。

功能2:父项复选框同步子项同列状态

当父项某列复选框状态改变时,遍历其所有子项,将子项对应列的复选框状态设置为与父项一致。

完整实现代码

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

class TreeWidgetHandler(QtCore.QObject):
    def __init__(self, tree):
        super().__init__()
        self.tree = tree
        self.tree.itemChanged.connect(self.on_item_changed)
        self.updating = False  # 防止信号循环触发

    def on_item_changed(self, item, column):
        if self.updating or column not in (1,2,3):
            return
        
        self.updating = True
        # 处理单个Item单选逻辑
        if item.checkState(column) == Qt.Checked:
            for col in (1,2,3):
                if col != column:
                    item.setCheckState(col, Qt.Unchecked)
        
        # 处理父项同步子项逻辑
        if item.childCount() > 0:
            target_state = item.checkState(column)
            for idx in range(item.childCount()):
                child_item = item.child(idx)
                child_item.setCheckState(column, target_state)
        
        self.updating = False

def main():
    app     = QtWidgets.QApplication(sys.argv)
    tree    = QtWidgets.QTreeWidget()
    tree.resize(500, 200)
    tree.setColumnCount(4)
    tree.setHeaderLabels(["pluto", "X", "Y", "Z"])
    handler = TreeWidgetHandler(tree)  # 绑定处理逻辑

    for i in range(3):
        parent = QtWidgets.QTreeWidgetItem(tree)
        parent.setText(0, "Parent {}".format(i))
        # 确保父项可被用户勾选
        parent.setFlags(parent.flags() | Qt.ItemIsUserCheckable)
        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(Qt.ItemIsUserCheckable | 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()

关键说明

  • self.updating标志位:用于避免修改复选框状态时重复触发itemChanged信号,防止逻辑循环。
  • 仅处理1/2/3列:因为第0列是文本列,不需要处理复选框状态。
  • 父项标志设置:必须给父项加上Qt.ItemIsUserCheckable标志,否则用户无法点击父项的复选框。
  • 子项同步逻辑:通过遍历父项的所有子项,直接设置对应列的复选框状态,确保与父项完全一致。

内容的提问来源于stack exchange,提问作者alvy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:15:21