QModelIndex returns wrong InternalPointer
-
wrote on 9 Aug 2022, 08:56 last edited by
I have an own Qt-Model class derieved from
QAbstractTableModel
. By background data structure consists ofRow
,Column
andCell
classes. So everyRow
has nCells
whose can bound to their belongingColumn
. TheCell
carries the actual Grid-field-value, Background-Color, Font, etc...My
index
-Method looks like this:QModelIndex TableModel::index(int row, int column, const QModelIndex& parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); // modelData is my background data-structure-class Cell* cell = modelData->Rows.at(row)->Cells.at(column); // retreiving the cell if (cell != Q_NULLPTR) return createIndex(row, column, cell); // Storing the Cell-object in every index return QModelIndex(); }
Now, when the Grid accesses data I have the
data
-method like this:QVariant TableModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); Cell* cell = static_cast<Cell*>(index.internalPointer()); // retreiving the Cell // it works when I say // Cell* cell = modelData->Rows.at(index.row()).Cells.at(index.column()); switch (role) { case Qt::DisplayRole: ... // return the value break; case Qt::DecorationRole: return cell->Column->Icon; case Qt::BackgroundRole: return cell->Column->BackgroundColor; case Qt::TextAlignmentRole: return static_cast<qint32>(cell->Column->TextAlignment); } return QVariant(); }
My problem is, that inside the
data
-function the internal-pointer (static_cast<Cell*>(index.internalPointer())
) always returns the sameCell
(row 0, column 0) and not theCell
according to the row and column coordinate. Because of this my grid has created all rows and columns but their cell-value is always the same because it only uses theCell
from row 0 and column 0 (example below to visualize the problem).
Retreiving theCell*
viamodelData->Rows.at(index.row()).Cells.at(index.column())
works though, but I really have to use the internalPointer because I would like to extend my model with hierarchy (parent-child-relations like a tree) or use the actualCell*
elsewhere. -
Hi,
Did you base your model on the Simple Tree Model example ?
Did you test your model using the Qt Model Tester class ?
-
Hi,
Did you base your model on the Simple Tree Model example ?
Did you test your model using the Qt Model Tester class ?
wrote on 10 Aug 2022, 06:20 last edited by me3ntal 8 Oct 2022, 07:07@SGaist
I tired the ModelTester and it didn't return anything wrong.My model is bit different from the Simple Tree Model Example. There it uses TreeItems with Columns and stores the
TreeIem*
in theinternalPointer()
. For me, I create aRow
and store every data inCell
s. The cells can be assigned to aColumn
where I store additional properties. When I'd like to get a specific entry from the Model (aModelIndex
so to speak) I take theindex.row()
and theindex.column()
and receive myCell
with this "coordinates" (Cell* cell = Rows.at(index.row()).Cells.at(index.column())
). I'd like to store thisCell*
inside theinternalPointer()
of the index. My guess is that something goes wrong whilst storing the pointer, although the correspondingCell*
is correct.Update:
When I store myRow*
in theinternalPointer
and get the respectiveCell
withstatic_cast<Row*>(index.internalPointer()).Cells.at(index.column())
it does work, but it is not really what I want, because for every row in theModelIndex
it would store the sameRow*
. -
One silly question but: did you check the pointer that you store in your index method ?
-
wrote on 11 Aug 2022, 06:30 last edited by
@SGaist
For everyRow
I create a uniqueCell*
. In myindex
-function I receive this pointer (created before) like this:Cell* cell = modelData->Rows.at(row)->Cells.at(column)
. This is fine, it is returning the right Cell corresponding to the givenrow
andcolumn
.
Or do you mean something else? -
I just realized something: I am wondering whether you might be hitting one of Python's memory handling mechanism.
Did you check whether you are getting the same index object again and again ?
What happens if you explicitly use the index method ?
-
wrote on 4 Jan 2023, 13:55 last edited by me3ntal 1 Apr 2023, 13:59
@SGaist
Okay your guess was pretty good tbh.I changed
data()
to useindex()
and not the passedQModelIndex
-parameter insteadconst QModelIndex& idx = this->index(index.row(), index.column(), index.parent()); Cell* cell = static_cast<Cell*>(index.internalPointer());
So I am retreiving the corresponding
QModelIndex
-reference from myindex()
-method and not from the passed parameter of thedata()
-method. And this works.I compared the addresses of the
QModelIndex
es fromindex()
and from the parameter ofdata()
and they are obviously different.
But when I compare the addresses of the internal pointers of both indexes, they are the same. Why can I retreive theCell*
only with a "fresh" reference coming from myindex()
-method and not with the passed parameter when their storedinternalPointer()
are the same?