QTableView rows disabled?
-
Hi,
i've implemented my first
QTableView
with PySide6. It is quite a 1:1 copy of a C++ solution.But contrary to C++ the table is like all rows are "disabled". They are grayed out.
Python:
C++:
How can that happen? Or better, what I am doing wrong?
My code to initialize the widget:
Python:
class AccountView(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_AccountView() self.ui.setupUi(self) self.ui.tableView.setObjectName(self.AccountViewTabIndentifier) self.ui.tableView.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) self.ui.tableView.setAlternatingRowColors(True) self.ui.tableView.horizontalHeader().setStretchLastSection(True) self.dbcontext = AccountDbContext() self.ui.tableView.setModel(self.dbcontext.frontendmodel) self.dbcontext.backendmodel.select() self.ui.tableView.setColumnHidden(0, True) self.ui.tableView.setEditTriggers(QAbstractItemView.EditTrigger.SelectedClicked)
C++:
AccountView::AccountView(QWidget *parent) : QWidget(parent) , ui(new Ui::AccountView) { ui->setupUi(this); ui->tableView->setObjectName(AccountViewTabIndentifier); ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView->setAlternatingRowColors(true); ui->tableView->horizontalHeader()->setStretchLastSection(true); m_dbcontext = new AccountDbContext(); ui->tableView->setModel(m_dbcontext->FrontendModel()); m_dbcontext->BackendModel()->select(); ui->tableView->setColumnHidden(0, true); ui->tableView->setEditTriggers(QAbstractItemView::SelectedClicked); }
Are there any settings I have overseen? I cannot find any real different between Python and C++ code.
-
Hi,
Did you check the actual values that are calculated for flags ?
I do not have a Python interpreter at hand but I recall that some operations are not 100% translatable as is from C++. -
here are also
flags
anddata
methods of the relevant data modeldef flags(self, index) -> Qt.ItemFlag: flags = super().flags(index) if index.isValid(): if not index.column() in self.editables: flags &= ~Qt.ItemFlag.ItemIsEditable if index.column() in self.bools: flags |= Qt.ItemFlag.ItemIsUserCheckable return flags def data(self, proxyIndex, role=...) -> any: ret = super().data(proxyIndex, role) if proxyIndex.column() in self.bools: match role: case Qt.ItemDataRole.DisplayRole: return None case Qt.ItemDataRole.CheckStateRole: return bool(super().data(proxyIndex, Qt.ItemDataRole.DisplayRole)) case Qt.ItemDataRole.EditRole: return None if role == Qt.ItemDataRole.DisplayRole: match proxyIndex.column(): case self.Datafield.BUCHUNGSTAG: return datetime.fromisoformat(ret).strftime("%d.%m.%Y") case self.Datafield.BETRAG: return locale.format_string("%.2f", ret, grouping=True) case self.Datafield.KATEGORIE: categorie = [k for k in self.categories if k.id() == ret] if len(categorie): return categorie[0].nameShort() return None case _: return ret if role == Qt.ItemDataRole.TextAlignmentRole: if proxyIndex.column() == self.Datafield.BETRAG: return Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter return ret return ret
-
Hi,
Did you check the actual values that are calculated for flags ?
I do not have a Python interpreter at hand but I recall that some operations are not 100% translatable as is from C++. -
@MasterQ
As @SGaist says all that matters here isflags()
, and probablyQt.ItemFlag.ItemIsEnabled
(if the items are disabled rather than just non-editable) orQt.ItemFlag.ItemIsEditable
. Have you tried making your override just goreturn super().flags(index)
with nothing else or comment out your override completely? Then you would know where the issue lies. -
@SGaist said in QTableView rows disabled?:
Did you check the actual values that are calculated for flags ?
Yes, but I was absently, obviously. I didn't recognize that detail.
The default flags returned from PySide is of value 130 which is
ItemIsEditable
|ItemHasNeverChildren
, while default flags from C++ is of value 163 which is additionallyItemIsEnabled
|ItemIsSelectable
.Oh dear, what a detail.
-
@SGaist said in QTableView rows disabled?:
@MasterQ That difference of behaviour between Python and C++ looks like a bug. Can you create a minimal script that shows this ?
That seems to be difficult. I tried this, which is very close to my setup here.
from PySide6.QtCore import QIdentityProxyModel from PySide6.QtSql import QSqlTableModel from PySide6.QtWidgets import QApplication, QMainWindow, QTableView class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) class BackendModel(QSqlTableModel): def __init__(self, parent=None): super().__init__(parent) print(self.insertColumn(0)) print(self.insertRow(0)) class FrontendModel(QIdentityProxyModel): def __init__(self, parent=None): super().__init__(parent) def flags(self, index): defaults = super().flags(index) print(defaults) return defaults app = QApplication() window = MainWindow() tableview = QTableView() frontendmodel = FrontendModel() backendmodel = BackendModel() frontendmodel.setSourceModel(backendmodel) tableview.setModel(frontendmodel) window.setCentralWidget(tableview) window.show() app.exec()
But with this code I get a value of 161 and not 130 for flags. I am confused.
In BackendModel the
flags
method is not oberloaded , so it is giving the unmodified value from BackendModel. In my code I checked flags before any modification!I haven't an idea why in the example above I get 161 and in my original code 130.
-
@JonB said in QTableView rows disabled?:
Then you will have to break down/build up till you find the difference in your code! Start by removing "front end identity model", just test directly on model (maybe non-SQL one as well as SQL one) and build back up from there.
If I would like to find a reason for that behavior!
At the moment I am satisfied to know about. There is an easy workaround as to set all flags by hand independently to what the framework does. That's enough for now. ... at least for me.
I am sorry, but to dig deeper into the issue is actually out of my scope.
-