【问题标题】:PyQt4 Qtreewidget - get hierarchy text if child checkbox is checkedPyQt4 Qtreewidget - 如果选中子复选框,则获取层次结构文本
【发布时间】:2014-04-20 14:39:00
【问题描述】:

我目前正在尝试做的是采用在底部子级别具有复选框的填充树(qtreewidget),如果选中该框,则将路径的文本返回给子级。我想这样做的原因是,如果检查了一个孩子,它将更改字典中键中的值。 (创建树的“原始”字典)。这是我的意思的视觉示例:

  1. 根据用户输入和服务器目录爬取,我们填充了一个看起来像这样的树: (只有最低级别的子项目有复选框。)对于可怕的树形图感到抱歉!希望这是有道理的...

已编辑

学习

-主题1

--日期

---[]c

---[]d

---[]e

-主题2

--日期

---[]g

---[]h

  1. 如果有人检查(例如)“g”级别的孩子,是否有办法以类似 [1, B, g] 或 1-Bg 或 1 的形式获取“g”的路径/B/g 等?

  2. 其中一个子级别(例如示例 A 和 B)也设置为用户可编辑。所以我需要来自树的信息,而不是最初填充树的信息。

我尝试打印 self.ui.treeWidget 索引,但没有真正获得我想要的东西。我觉得好像有一个简单的解决方案,但我似乎无法找到它。希望有人可以提供帮助!

实际代码片段:

    for h,study in enumerate(tree_dict['study']):
        study_name = study['study_name']
        treeSTUDY = QtGui.QTreeWidgetItem(self.ui.treeWidget, [study_name])
        treeSTUDY.setFlags(QtCore.Qt.ItemIsEnabled)
        self.ui.treeWidget.expandItem(treeSTUDY)            

        for i,subject in enumerate(study['subject']):
            subject = subject['ID']
            treeSUBJECT = QtGui.QTreeWidgetItem(treeSTUDY, [subject_id])
            treeSUBJECT.setFlags(QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled)

            for j,visit in enumerate(subject['visit']):
                scan_date = visit['date']                     
                treeDATE = QtGui.QTreeWidgetItem(treeSUBJECT, [scan_date[4:6])
                treeDATE.setFlags(QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled)

                for k,ser in enumerate(visit['series']):
                    s_name = ser['name'] + '-' + ser['description']
                    count =  str(ser['count'])
                    treeSCAN = QtGui.QTreeWidgetItem(treeDATE)
                    treeSCAN.setFlags(QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable)
                    treeSCAN.setCheckState(0, QtCore.Qt.Unchecked)   
                    treeSCAN.setText(0, s_name)
                    treeSCAN.setText(1, ser['time'])
                    treeSCAN.setText(2, ser['number'])
                    treeSCAN.setText(3, 'count')

【问题讨论】:

    标签: python pyqt pyqt4 qtreewidget qcheckbox


    【解决方案1】:

    您所需要的只是一种方法,该方法沿着父/子链获取每个项目的文本,直到父项为None

    def getTreePath(self, item):
        path = []
        while item is not None:
            path.append(str(item.text(0)))
            item = item.parent()
        return '/'.join(reversed(path))
    

    更新

    这是一个演示脚本,展示了如何获取选中的项目并检索其路径:

    from PyQt4 import QtCore, QtGui
    
    class Window(QtGui.QWidget):
        def __init__(self):
            QtGui.QWidget.__init__(self)
            self.tree = QtGui.QTreeWidget(self)
            self.tree.setHeaderHidden(True)
            for index in range(2):
                parent = self.addItem(self.tree, 'Item%d' % index)
                for color in 'Red Green Blue'.split():
                    subitem = self.addItem(parent, color)
                    for letter in 'ABC':
                        self.addItem(subitem, letter, True, False)
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.tree)
            self.tree.itemChanged.connect(self.handleItemChanged)
    
        def addItem(self, parent, text, checkable=False, expanded=True):
            item = QtGui.QTreeWidgetItem(parent, [text])
            if checkable:
                item.setCheckState(0, QtCore.Qt.Unchecked)
            else:
                item.setFlags(
                    item.flags() & ~QtCore.Qt.ItemIsUserCheckable)
            item.setExpanded(expanded)
            return item
    
        def handleItemChanged(self, item, column):
            if item.flags() & QtCore.Qt.ItemIsUserCheckable:
                path = self.getTreePath(item)
                if item.checkState(0) == QtCore.Qt.Checked:
                    print('%s: Checked' % path)
                else:
                    print('%s: UnChecked' % path)
    
        def getTreePath(self, item):
            path = []
            while item is not None:
                path.append(str(item.text(0)))
                item = item.parent()
            return '/'.join(reversed(path))
    
    if __name__ == '__main__':
    
        import sys
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.setGeometry(500, 300, 250, 450)
        window.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 感谢您的回复,这绝对是有道理的!我认为我仍然不太了解的一件事是如何让它只在检查的子/路径上运行。我知道如何使用 checkstate 来添加 if 语句,但是在您的示例代码中我会在哪里指定子项?这不是必需的,所以它不只是给我树上每个项目的路径吗? (我是 python 和 QT 的新手,所以如果这是一个非常简单/初学者的问题,我深表歉意。)
    • @rocketstothemoon。我在我的答案中添加了一个演示脚本,它显示了这一切是如何结合在一起的。
    • 太棒了!我现在完全明白了。非常感谢,它正是我想要的。
    • 我玩过您的示例并认为我理解它,但是当我尝试将它集成到我的代码中时,它的工作方式不同。 (这非常是我的初学者知识水平出来的)。我更新了我的帖子以包含我的实际代码,因为我认为我的问题是我以不同的方式填充我的树。我的树是从前面在代码“tree_dict”中返回的字典中填充的。您是否有机会看到为什么您的示例可能不适用于我的树?
    • @rocketstothemoon。好吧,不,因为你实际上并没有说什么“不起作用”;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多