QTableView checkbox is never checked
-
I have a QTableView with custom model, for which I want first column to be checkable.
I am able to see the checkbox, but even if I force it to be checked, it is always unchecked.Detailed explained here: https://stackoverflow.com/questions/74380799/qtableview-checkbox-is-never-checked
What am I doing wrong?
-
I have a QTableView with custom model, for which I want first column to be checkable.
I am able to see the checkbox, but even if I force it to be checked, it is always unchecked.Detailed explained here: https://stackoverflow.com/questions/74380799/qtableview-checkbox-is-never-checked
What am I doing wrong?
@tilz0R
I am not spotting anything wrong in your code atm. However, I do not know what yourTableView_DataModel
base class does or does not implement forQAbstractItemModel
, in case it is missing something. This probably is not an issue since the table seems to look OK, but just a thought.One thing troubles me a bit in your picture. Why does column #0, the
Id
/checkbox cell column, not show thereturn item.id
you have for that in yourdata()
for theDisplayRole
? Is that value perchanceNone
/NULL? I have a vague possible recollection that if the value is null for a cell then Qt does not draw that cell at all, maybe not even any checkstate? Try making that column return some non-null value, does that then cause it to respect the checkstate?? -
Thanks for your reply.
I am adding my extension of the model, that extends the required mode.
from pathlib import Path from PySide6.QtWidgets import * from PySide6.QtCore import * from PySide6.QtUiTools import * from datatypes import * class TableView_DataModel(QAbstractTableModel): """ https://doc.qt.io/qt-6/qabstractitemmodel.html """ _tableData = [] _columnNames = [] def __init__(self, parent = None): super(TableView_DataModel, self).__init__(parent) self._tableData = [] def index(self, row, column, parent = QModelIndex()): return self.createIndex(row, column, self._tableData[row]) def columnCount(self, parent): return len(self._columnNames) def rowCount(self, parent): return len(self._tableData) def parent(self, index): return QModelIndex() # Structure header data for columns and rows def headerData(self, section, orientation, role): if role != Qt.ItemDataRole.DisplayRole: return None if orientation == Qt.Orientation.Horizontal: # Columns return self._columnNames[section] else: # Rows return section + 1 # Load full entry to the table model def load(self, data): self.beginResetModel() self._tableData = data self.endResetModel() # Append new entry def append(self, entry): self.beginResetModel() self._tableData.append(entry) self.endResetModel() # Get data entry for index def get_row(self, index): return self._tableData[index] # Return data object def getDataAll(self): return self._tableData
Column 0 properly shows the ID number of the record from my custom item class. Actually as You can see, I force to return
Qt.Checked
and no success. PySide6 is 6.4.0 -
Thanks for your reply.
I am adding my extension of the model, that extends the required mode.
from pathlib import Path from PySide6.QtWidgets import * from PySide6.QtCore import * from PySide6.QtUiTools import * from datatypes import * class TableView_DataModel(QAbstractTableModel): """ https://doc.qt.io/qt-6/qabstractitemmodel.html """ _tableData = [] _columnNames = [] def __init__(self, parent = None): super(TableView_DataModel, self).__init__(parent) self._tableData = [] def index(self, row, column, parent = QModelIndex()): return self.createIndex(row, column, self._tableData[row]) def columnCount(self, parent): return len(self._columnNames) def rowCount(self, parent): return len(self._tableData) def parent(self, index): return QModelIndex() # Structure header data for columns and rows def headerData(self, section, orientation, role): if role != Qt.ItemDataRole.DisplayRole: return None if orientation == Qt.Orientation.Horizontal: # Columns return self._columnNames[section] else: # Rows return section + 1 # Load full entry to the table model def load(self, data): self.beginResetModel() self._tableData = data self.endResetModel() # Append new entry def append(self, entry): self.beginResetModel() self._tableData.append(entry) self.endResetModel() # Get data entry for index def get_row(self, index): return self._tableData[index] # Return data object def getDataAll(self): return self._tableData
Column 0 properly shows the ID number of the record from my custom item class. Actually as You can see, I force to return
Qt.Checked
and no success. PySide6 is 6.4.0@tilz0R
Damn, I was hoping you had nothing in ID column and that was cause of no checking :(I can only suggest you strip your code down to absolute minimum to see behaviour. Might you even try it with, say, a
QStandardItemModel
to eliminate the custom model and see whether it ever/never works? -
This is the minimum, and I'm still not able to see it pressed
from pathlib import Path from PySide6.QtCore import * from PySide6.QtGui import * from datatypes import * from tableview_datamodel import * # Table model class AbsMinModel(QAbstractTableModel): _columnNames = ['Id'] _tableData = [[1], [2], [3]] def __init__(self, parent = None): super(AbsMinModel, self).__init__(parent) def data(self, index, role): if not index.isValid(): return None item = index.internalPointer() if role == Qt.ItemDataRole.DisplayRole: return 'data' elif role == Qt.ItemDataRole.CheckStateRole and index.column() == 0: return Qt.CheckState.Checked return None # Set data to apply new state def setData(self, index, value, role=Qt.EditRole): if not index.isValid(): return False if role == Qt.CheckStateRole: # Set checked state to internal object item = index.internalPointer() item.checked = value self.dataChanged.emit(index, index) return True return False # Apply flags def flags(self, index): fl = TableView_DataModel.flags(self, index) if index.column() == 0: fl |= Qt.ItemIsEditable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsSelectable return fl def index(self, row, column, parent = QModelIndex()): return self.createIndex(row, column, self._tableData[row]) def columnCount(self, parent): return len(self._columnNames) def rowCount(self, parent): return len(self._tableData) def parent(self, index): return QModelIndex() # Load full entry to the table model def load(self, data): self.beginResetModel() self._tableData = data self.endResetModel() # Append new entry def append(self, entry): self.beginResetModel() self._tableData.append(entry) self.endResetModel() # Structure header data for columns and rows def headerData(self, section, orientation, role): if role != Qt.ItemDataRole.DisplayRole: return None if orientation == Qt.Orientation.Horizontal: return self._columnNames[section] else: return section + 1
I must be failing somewhere - jesus
-
There were some bugs regarding returning Qt.CheckState from item models (see PYSIDE-1930, please make sure to use a recent version (6.4.0.1).
-
There were some bugs regarding returning Qt.CheckState from item models (see PYSIDE-1930, please make sure to use a recent version (6.4.0.1).
@friedemannkleint , @tilz0R
Damn, I've just wasted my time! :) Fired up an old Ubuntu 19, PyQt5.x, got rid oftableview_datamodel
, put in a main program, created the model, attached to the view (all part of minimal example!).Worked fine for me, shows checkboxes checked on startup. Was going to post screenshot, but not needed now.
I did wonder about that
int(Qt.CheckState.Checked)
. Worked without for me but under PyQt5 and Qt5. -
Not possible to download it with pip
python -m pip install PyQt6==6.4.0.1 --proxy ERROR: Could not find a version that satisfies the requirement PyQt6==6.4.0.1 (from versions: 6.0.0, 6.0.1, 6.0.2, 6.0.3, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.3.0, 6.3.1, 6.4.0) ERROR: No matching distribution found for PyQt6==6.4.0.1