Reputation: 808
I am writing an application in PySide2 and I have developed a class inheriting from Qdialog to display a list with checkboxes:
The code of the class:
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)
The result (plus some extra code):
As it is, you can check multiple checkboxes, but I need to make it a single selection.
Note the line:
self.listView.setSelectionMode(QTableView.NoSelection)
At first, I thought setSelectionMode
was responsible for this behaviour but this controls only the highlighting on the items of the list and not its checkboxes. Therefore I set it to NoSelection
for not highlighting the text part, the checkboxes are working!
Is there an easy way to set the selection mode to single? Or should I overload the signal that controls the box checking to unselect all the boxes and then select the one I clicked?
Upvotes: 0
Views: 746
Reputation: 6584
An easy way to do that it to use a proxy model which will handle the single selection and the signal QStandardItemModel::itemChanged
to know when user clicks on an item.
For example:
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
The checkSingleCheck
method will be called when the user clicks on an item. But, if you want to be able to edit the items, you have to adapt this function.
Upvotes: 1