检查影响 QListWidget 中特定项目集的项目 [英] Check an item that effects on a certain set of items within QListWidget

查看:58
本文介绍了检查影响 QListWidget 中特定项目集的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我已经创建并添加到 QListWidget 的项目列表,其中这些项目被分类".

I have a list of items that I have created and added into the QListWidget in which these items are 'categorized'.

在我下面的代码中,我有 2 个类别 - -- All Nums ---- All Letters --.在每个类别中,它都有其子项目.

In my following code, I have 2 categories - -- All Nums -- and -- All Letters --. And within each category, it has its sub items within.

由于我已将所有项目设为可勾选,是否可以勾选/取消勾选这些标题项目并对其子项目产生影响?

As I have made all items checkable, is it possible to check/uncheck these header items and have it effected on its sub items?

例如.如果我检查 -- All Nums,所有 num_items 也会被检查.如果我取消选中它,他们也会取消选中.

Eg. If I check -- All Nums, all the num_items will be checked too. And if I uncheck it, they will be uncheck too.


class TestDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(TestDialog, self).__init__()
        self.listWidget = QtGui.QListWidget()

        all_num = QtGui.QListWidgetItem('-- All Nums --')
        self.listWidget.addItem(all_num)

        num_items = ['One', 'Two', 'Three']
        for num in num_items:
            self.listWidget.addItem(num)

        all_letters = QtGui.QListWidgetItem('-- All Letters --')
        self.listWidget.addItem(all_letters)

        letter_items = ['One', 'Two', 'Three']
        for letter in letter_items:
            self.listWidget.addItem(letter)

        for index in range(self.listWidget.count()):
            item = self.listWidget.item(index)
            item.setFlags(
                item.flags() |
                QtCore.Qt.ItemIsUserCheckable |
                QtCore.Qt.ItemIsEditable
            )
            item.setCheckState(QtCore.Qt.Unchecked)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.listWidget)


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = TestDialog()
    w.show()
    sys.exit(app.exec_())

推荐答案

解决思路是使用一个角色来存储项目是否属于类别的信息,另一个角色表示项目之间的父级关系,以及然后使用委托修改它们是否满足要求.

The solution idea is to use a role to store the information if the item is a category or not, and another role that indicates the parentship between the items, and then modify if they meet the requirement using a delegate for it.

from PyQt4 import QtCore, QtGui


IsCategoryRole = QtCore.Qt.UserRole
ParentRole = QtCore.Qt.UserRole + 1


class CategoryDelegate(QtGui.QStyledItemDelegate):
    def editorEvent(self, event, model, option, index):
        old_state = model.data(index, QtCore.Qt.CheckStateRole)
        res = super(CategoryDelegate, self).editorEvent(
            event, model, option, index
        )
        current_state = model.data(index, QtCore.Qt.CheckStateRole)
        if old_state != current_state:
            if index.data(IsCategoryRole):
                pix = QtCore.QPersistentModelIndex(index)
                for i in range(model.rowCount()):
                    ix = model.index(i, 0)
                    if pix == ix.data(ParentRole):
                        model.setData(
                            ix, current_state, QtCore.Qt.CheckStateRole
                        )
        return res


class ListWidget(QtGui.QListWidget):
    def __init__(self, parent=None):
        super(ListWidget, self).__init__(parent)
        delegate = CategoryDelegate(self)
        self.setItemDelegate(delegate)

    def addCategory(self, text):
        item = ListWidget.create_checkable_item(text)
        item.setData(IsCategoryRole, True)
        self.addItem(item)
        return item

    def addItemToCategory(self, category_item, text):
        item = ListWidget.create_checkable_item(text)
        item.setData(IsCategoryRole, False)
        ix = self.indexFromItem(category_item)
        pix = QtCore.QPersistentModelIndex(ix)
        item.setData(ParentRole, pix)
        self.addItem(item)
        return item

    @staticmethod
    def create_checkable_item(text):
        item = QtGui.QListWidgetItem(text)
        item.setFlags(
            item.flags()
            | QtCore.Qt.ItemIsUserCheckable
            | QtCore.Qt.ItemIsEditable
        )
        item.setCheckState(QtCore.Qt.Unchecked)
        return item


class TestDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(TestDialog, self).__init__()
        self.listWidget = ListWidget()

        all_num = self.listWidget.addCategory("-- All Nums --")
        num_items = ["One", "Two", "Three"]
        for num in num_items:
            self.listWidget.addItemToCategory(all_num, num)

        all_letters = self.listWidget.addCategory("-- All Letters --")

        letter_items = ["One", "Two", "Three"]
        for letter in letter_items:
            self.listWidget.addItemToCategory(all_letters, letter)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.listWidget)


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    w = TestDialog()
    w.show()
    sys.exit(app.exec_())

这篇关于检查影响 QListWidget 中特定项目集的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆