【问题标题】:Set SingleSelection in QListView在 QListView 中设置 SingleSelection
【发布时间】:2019-05-02 10:38:47
【问题描述】:

我正在 PySide2 中编写一个应用程序,并且我开发了一个继承自 Qdialog 的类来显示带有复选框的列表:

类的代码:

class ListDialog(QDialog):
    def __init__(self, items, all_checked = False, parent=None):
        super(ListDialog, self).__init__(parent=parent)
        self.setWindowTitle(title)
        form = QFormLayout(self)

        self.listView = QListView(self)
        self.listView.setSelectionMode(QTableView.NoSelection)

        form.addRow(self.listView)
        self.model = QStandardItemModel(self.listView)
        for item in items:
            # create an item with a caption
            standardItem = QStandardItem(item)
            standardItem.setCheckable(True)
            standardItem.setEditable(False)
            if all_checked:
                standardItem.setCheckState(Qt.Checked)
            self.model.appendRow(standardItem)
        self.listView.setModel(self.model)

结果(加上一些额外的代码):

事实上,您可以选中多个复选框,但我需要将其设为单选

注意这一行:

self.listView.setSelectionMode(QTableView.NoSelection)

起初,我认为setSelectionMode 是造成这种行为的原因,但它只控制列表项目的突出显示,而不是其复选框。因此,我将其设置为 NoSelection 以不突出显示文本部分,复选框正在工作!

有没有一种简单的方法可以将选择模式设置为单一?或者我应该重载控制框检查的信号以取消选择所有框,然后选择我点击的那个?

【问题讨论】:

    标签: python python-3.x pyside2


    【解决方案1】:

    一种简单的方法是使用代理模型来处理单个选择和信号QStandardItemModel::itemChanged,以了解用户何时单击项目。

    例如:

    class SingleCheckProxyModel(QIdentityProxyModel):
        def __init__(self, model, parent=None):
            super().__init__(parent)
            model.itemChanged.connect(self.checkSingleCheck)
            self.setSourceModel(model)
            self.currentItemChecked = None
    
        def checkSingleCheck(self, item):
            if self.currentItemChecked:
                self.currentItemChecked.setCheckState(Qt.Unchecked)
            if item.checkState(): # Allows the user to uncheck then check the same item
                self.currentItemChecked = item
            else:
                self.currentItemChecked = None
    
    
    class ListDialog(QDialog):
        def __init__(self, items, all_checked = False, parent=None):
            super(ListDialog, self).__init__(parent=parent)
            self.setWindowTitle("kjnve")
            form = QFormLayout(self)
    
            self.listView = QListView(self)
            self.listView.setSelectionMode(QTableView.NoSelection)
    
            form.addRow(self.listView)
            self.model = QStandardItemModel(self.listView)
            for item in items:
                # create an item with a caption
                standardItem = QStandardItem(item)
                standardItem.setCheckable(True)
                standardItem.setEditable(False)
                if all_checked:
                    standardItem.setCheckState(Qt.Checked)
                self.model.appendRow(standardItem)
            self.listView.setModel(SingleCheckProxyModel(self.model)) # Use proxy
    

    checkSingleCheck 方法将在用户点击一个项目时被调用。但是,如果你想能够编辑项目,你必须适应这个功能。

    【讨论】:

    • QIdentityProxyModel 是 QtCore 的一部分。实际上,您不需要使用代理模型,可以将方法直接放在您的ListDialog 类中。我更喜欢使用代理来拆分视图和模型之间的业务逻辑。
    • 好吧,它正在工作。我唯一要更改的是self.currentItemChecked.setCheckState(False)self.currentItemChecked.setCheckState(Qt.Unchecked)
    • 可以提供不带代理的方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多