Python 在QListView中设置SingleSelection

Python 在QListView中设置SingleSelection,python,python-3.x,pyside2,Python,Python 3.x,Pyside2,我正在用PySide2编写一个应用程序,我开发了一个继承自Qdialog的类来显示带有复选框的列表: 课程代码: class ListDialog(QDialog): def __init__(self, items, all_checked = False, parent=None): super(ListDialog, self).__init__(parent=parent) self.setWindowTitle(title) fo

我正在用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
,因为没有突出显示文本部分,复选框起作用了


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

一种简单的方法是使用代理模型来处理单个选择,并使用信号
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)
可以提供没有代理的方法吗?