Установить SingleSelection в QListView - PullRequest
0 голосов
/ 02 мая 2019

Я пишу приложение в 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)

Результат (плюс некоторый дополнительный код):

list image example

На самом деле, вы можете проверить несколько флажков, но мне нужно сделать это одиночный выбор .

Обратите внимание на строку:

self.listView.setSelectionMode(QTableView.NoSelection)

Сначала я думал, что setSelectionMode был ответственен за это поведение, но это контролирует только выделение элементовсписка, а не его флажки.Поэтому я установил его на NoSelection, чтобы не выделять текстовую часть, флажки работают!

Есть ли простой способ установить режим выделения на одиночный?Или я должен перегрузить сигнал, который контролирует проверку ящиков, чтобы отменить выбор всех ящиков, а затем выбрать тот, который я нажал?

1 Ответ

1 голос
/ 02 мая 2019

Простой способ сделать это - использовать модель прокси, которая будет обрабатывать одиночный выбор и сигнал 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 вызывается, когда пользователь нажимает на элемент. Но если вы хотите иметь возможность редактировать элементы, вы должны адаптировать эту функцию.

...