QTreeWidget 中父子节点的选中状态的相互影响和改变python版

##QTreeWidget 中父子节点的选中状态的相互影响和改变python版
##源代码来源于 C#、C++ 版本,经过修改后为python版本
##只要正确安装了 PyQt5 就可以正常运行
## checkState 选定状态有三种:选定=Qt.Checked、
##不选=Qt.UnChecked、半选=Qt.PartiallyChecked
##父节点 选定=Qt.Checked 则子节点全部选定=Qt.Checked,
##     包括更深层次的子节点(遍历所有子节点)
##父节点 不选=Qt.UnChecked 则子节点全部不选=Qt.UnChecked,
##     包括更深层次的子节点(遍历所有子节点)
##子节点 选定=Qt.Checked ,兄弟节点也全选定=Qt.Checked,
##     则父节点选定=Qt.Checked(一直遍历到根节点)
##子节点 选定=Qt.Checked ,兄弟节点半选=Qt.PartiallyChecked,
##     则父节点半选=Qt.PartiallyChecked(一直遍历到根节点)


import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt,QSignalBlocker
#子节点更新父节点状态到根节点 父节点更新到子节点 完美
class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super(MainWindow,self).__init__(parent)
        self.setWindowTitle("树形结构 TreeWidget 2 - by cxz")

        self.treeWidget=QTreeWidget()
        self.resize(400,900)
        self.setCentralWidget(self.treeWidget)
        self.treeWidget.header().hide()
        self.treeWidget.itemChanged.connect(lambda itm:self.onTreeItemChanged(itm))
        self.setStyleSheet('font-size:20px')
        self.initUI()

    def initUI(self):
        self.treeWidget.setColumnCount(1)
        root=QTreeWidgetItem(self.treeWidget)
        root.setText(0,"全部")
        root.setCheckState(0,Qt.Checked)
        xingqi=['星期一','星期二','星期三','星期四','星期五']
        wubie=['上午','下午']
        sjdList=[]
        for xq in xingqi:
            for wb in wubie:
                for n in range(1,5):
                    sjdList.append([xq,wb,n])
        xingqiNode,wubieNode,jieciNode=None,None,None
        for n in range(len(sjdList)):
            if sjdList[n][0]!=sjdList[n-1][0]:
                xingqiNode=QTreeWidgetItem(root)
                xingqiNode.setText(0,sjdList[n][0])
                xingqiNode.setData(0,Qt.UserRole,sjdList[n][0])
                xingqiNode.setCheckState(0,Qt.Checked)
            if sjdList[n][1]!=sjdList[n-1][1]:
                wubieNode=QTreeWidgetItem(xingqiNode)
                wubieNode.setText(0,sjdList[n][1])
                wubieNode.setData(0,Qt.UserRole,sjdList[n][0])
                wubieNode.setCheckState(0,Qt.Checked)
            jieciNode=QTreeWidgetItem(wubieNode)
            jieciNode.setText(0,'第'+str(sjdList[n][2])+'节')
            jieciNode.setData(0,Qt.UserRole,sjdList[n][0])
            jieciNode.setCheckState(0,Qt.Checked)
        self.treeWidget.addTopLevelItem(root)
        self.treeWidget.expandAll()
        
    def updateChildItemCheckState(self,item):
        if item is None:
            return
        childCount = item.childCount()
        checkState = item.checkState(0)
        for i in range(childCount):
            childItem = item.child(i)
            if childItem:
                childItem.setCheckState(0, checkState)
                self.updateChildItemCheckState(childItem)

    def updateParentItemCheckState(self,item):
        if item is None:
            return
        parentItem = item.parent()
        if parentItem is None:
            return
        childCount = parentItem.childCount()
        childCheckedCount = self.getChildItemCheckedCount(parentItem)
        if childCount == childCheckedCount:
            parentItem.setCheckState(0, Qt.Checked)
        elif childCheckedCount > 0:
            parentItem.setCheckState(0, Qt.PartiallyChecked)
        elif childCheckedCount == 0:
            parentItem.setCheckState(0, Qt.Unchecked)
        self.updateParentItemCheckState(parentItem)

    def getChildItemCheckedCount(self,item):
        if item is None:
            return 0
        childCount = item.childCount()
        checkedCount = 0
        for n in range(childCount):
            childItem = item.child(n)
            if childItem:
                if childItem.checkState(0) == Qt.Checked:
                    checkedCount += 1
        return checkedCount

    def onTreeItemChanged(self,item):
        if item is None:
            return
        blocker = QSignalBlocker(self.treeWidget)#必要阻塞其他信号
        self.updateChildItemCheckState(item)
        self.updateParentItemCheckState(item)

if __name__=="__main__":
    app=QApplication(sys.argv)
    window=MainWindow()
    window.show()
    sys.exit(app.exec_())

##有兴趣愿意交流的朋友可以V我 cxz7558 Q我 190561115,相互学习

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值