QSqlTableModel proxy not working
-
Hi.
I collide with an issue i couldnt understand.
I have proxy which translate row into a tree.
Its worked well with QStandardItemModel.
But its broken with QSqlTableModel.Both models could be shown via QTableView. But Sql couldnt in QTreeView (no childs found)
Is there any difference between models which i should care with proxy?
I thought that there shouldnt. (both could be viewed in table, so functions for dhow is same)Thanks for any impulse in any direction (no idea what to do)
Here is my code, just in case ...
struct StandartProxyInternal{ int row; }; class StandardTreeProxy : public QAbstractProxyModel { // QAbstractItemModel interface public: QModelIndex index(int row, int column, const QModelIndex &parent) const { if(!parent.isValid()) { return createIndex(row, column, nullptr); } return createIndex(row, column, new StandartProxyInternal{parent.row()}); } QModelIndex parent(const QModelIndex &child) const { if(!child.isValid()) { return QModelIndex(); } auto *internal = static_cast<StandartProxyInternal*>(child.internalPointer()); if(!internal) { return QModelIndex(); } return index(internal->row, 0, QModelIndex()); } int rowCount(const QModelIndex &parent) const { if(!parent.isValid()) { return sourceModel()->rowCount(); } return sourceModel()->columnCount() - 1; } int columnCount(const QModelIndex &parent) const { return 1; } // QAbstractProxyModel interface public: QModelIndex mapToSource(const QModelIndex &proxyIndex) const { auto *internal = static_cast<StandartProxyInternal*>(proxyIndex.internalPointer()); if(!internal) { return sourceModel()->index(proxyIndex.row(), 0); } int row = internal->row; int col = proxyIndex.row() + 1; return sourceModel()->index(row, col); } QModelIndex mapFromSource(const QModelIndex &sourceIndex) const { if(sourceIndex.column() == 0) { return index(sourceIndex.row(), 0, QModelIndex()); } return index(sourceIndex.column() - 1, 0, createIndex(sourceIndex.row(), 0)); } // QAbstractItemModel interface public: bool hasChildren(const QModelIndex &parent) const { if(!parent.isValid()) { return sourceModel()->columnCount() > 0 ? true : false; } auto *internal = static_cast<StandartProxyInternal*>(parent.internalPointer()); if(!internal) { return true; } return false; } // QAbstractProxyModel interface public: void setSourceModel(QAbstractItemModel *sourceModel) { QAbstractProxyModel::setSourceModel(sourceModel); connect(sourceModel, &QAbstractItemModel::dataChanged, this, &QAbstractProxyModel::dataChanged); connect(sourceModel, &QAbstractItemModel::rowsInserted, this, &QAbstractProxyModel::rowsInserted); } }; -
Here is a debug log i got for sql version:
hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) rowCount QModelIndex(-1,-1,0x0,QObject(0x0)) index 0 0 QModelIndex(-1,-1,0x0,QObject(0x0)) parent QModelIndex(0,0,0x0,QAbstractProxyModel(0x2acd5fa1d90)) 0x0And same log for standard:
hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) rowCount QModelIndex(-1,-1,0x0,QObject(0x0)) index 0 0 QModelIndex(-1,-1,0x0,QObject(0x0)) hasChild QModelIndex(0,0,0x0,QAbstractProxyModel(0x2096f6e1660)) parent QModelIndex(0,0,0x0,QAbstractProxyModel(0x2096f6e1660)) 0x0Third hasChildren not called.
How could that happened? All i did is switch model. (I understand that its difficult to understand without the code of logging) -
Hi.
I collide with an issue i couldnt understand.
I have proxy which translate row into a tree.
Its worked well with QStandardItemModel.
But its broken with QSqlTableModel.Both models could be shown via QTableView. But Sql couldnt in QTreeView (no childs found)
Is there any difference between models which i should care with proxy?
I thought that there shouldnt. (both could be viewed in table, so functions for dhow is same)Thanks for any impulse in any direction (no idea what to do)
Here is my code, just in case ...
struct StandartProxyInternal{ int row; }; class StandardTreeProxy : public QAbstractProxyModel { // QAbstractItemModel interface public: QModelIndex index(int row, int column, const QModelIndex &parent) const { if(!parent.isValid()) { return createIndex(row, column, nullptr); } return createIndex(row, column, new StandartProxyInternal{parent.row()}); } QModelIndex parent(const QModelIndex &child) const { if(!child.isValid()) { return QModelIndex(); } auto *internal = static_cast<StandartProxyInternal*>(child.internalPointer()); if(!internal) { return QModelIndex(); } return index(internal->row, 0, QModelIndex()); } int rowCount(const QModelIndex &parent) const { if(!parent.isValid()) { return sourceModel()->rowCount(); } return sourceModel()->columnCount() - 1; } int columnCount(const QModelIndex &parent) const { return 1; } // QAbstractProxyModel interface public: QModelIndex mapToSource(const QModelIndex &proxyIndex) const { auto *internal = static_cast<StandartProxyInternal*>(proxyIndex.internalPointer()); if(!internal) { return sourceModel()->index(proxyIndex.row(), 0); } int row = internal->row; int col = proxyIndex.row() + 1; return sourceModel()->index(row, col); } QModelIndex mapFromSource(const QModelIndex &sourceIndex) const { if(sourceIndex.column() == 0) { return index(sourceIndex.row(), 0, QModelIndex()); } return index(sourceIndex.column() - 1, 0, createIndex(sourceIndex.row(), 0)); } // QAbstractItemModel interface public: bool hasChildren(const QModelIndex &parent) const { if(!parent.isValid()) { return sourceModel()->columnCount() > 0 ? true : false; } auto *internal = static_cast<StandartProxyInternal*>(parent.internalPointer()); if(!internal) { return true; } return false; } // QAbstractProxyModel interface public: void setSourceModel(QAbstractItemModel *sourceModel) { QAbstractProxyModel::setSourceModel(sourceModel); connect(sourceModel, &QAbstractItemModel::dataChanged, this, &QAbstractProxyModel::dataChanged); connect(sourceModel, &QAbstractItemModel::rowsInserted, this, &QAbstractProxyModel::rowsInserted); } };Hi,
I found related threads, maybe it helps.
- https://www.qtcentre.org/threads/69098-Viewing-QSqlTableModel-in-QTreeView-through-a-proxy-model
- https://stackoverflow.com/questions/68145427/issues-with-mapping-qsqltablemodel-to-qtreeview-using-qabstractproxymodel
And here is an example:
(can't tell if this still works, since it's pretty old) -
Thanks. Try to compare with my solution.
My misunderstand is that:
(StandardModel is worked, but SqlModel isnt, but TableView in both cases is ok)

so there is an internal difference between them?
I though that every view should work for every model (as TableView)
My example work for only single row in model and not support anything, just try to use proxy.
-
How would you map a table to a tree? You most likely did something wrong in your model.
-
I found out that all QModelIndexes is Invalid when its an sql one.
But since my first column is a root indexes for other columns - thew added in the view.QModelIndex mapToSource(const QModelIndex &proxyIndex) const { auto *internal = static_cast<StandartProxyInternal*>(proxyIndex.internalPointer()); if(!internal) { return sourceModel()->index(proxyIndex.row(), 0); } int row = internal->row; int col = proxyIndex.row() + 1; return sourceModel()->index(row, col); } QModelIndex mapFromSource(const QModelIndex &sourceIndex) const { if(sourceIndex.column() == 0) { return index(sourceIndex.row(), 0, QModelIndex()); } return index(sourceIndex.column() - 1, 0, createIndex(sourceIndex.row(), 0)); }But it exactly same for standardmodel, which work
-
Here is a debug log i got for sql version:
hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) rowCount QModelIndex(-1,-1,0x0,QObject(0x0)) index 0 0 QModelIndex(-1,-1,0x0,QObject(0x0)) parent QModelIndex(0,0,0x0,QAbstractProxyModel(0x2acd5fa1d90)) 0x0And same log for standard:
hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) hasChild QModelIndex(-1,-1,0x0,QObject(0x0)) rowCount QModelIndex(-1,-1,0x0,QObject(0x0)) index 0 0 QModelIndex(-1,-1,0x0,QObject(0x0)) hasChild QModelIndex(0,0,0x0,QAbstractProxyModel(0x2096f6e1660)) parent QModelIndex(0,0,0x0,QAbstractProxyModel(0x2096f6e1660)) 0x0Third hasChildren not called.
How could that happened? All i did is switch model. (I understand that its difficult to understand without the code of logging) -
@Christian Ehrlicher Thanks for your links, from which i found out about flags existance.
It happened because of this check insede Qt:
if (parent.flags() & Qt::ItemNeverHasChildren)and it flag always in my QModelIndex
QFlags<Qt::ItemFlag>(ItemIsSelectable|ItemIsEditable|ItemIsEnabled|ItemNeverHasChildren)
Default flags settings is a key difference between QStandardModel and QSqlTabbleModel!
-
S SergeyK12 has marked this topic as solved on
-
S SergeyK12 has marked this topic as solved on
-
S SergeyK12 has marked this topic as solved on