How do deal with external changes to a model
-
I have a QAbstractItemModel that represents a list of items from a class looking like this:
class item { public: QHash<category, QVariant> values; };
These
item
s belong to a a parent class calledregister
, which simultaneously has a list ofcategory
objects.
Each item has a value for each category - categories can be added and removed using a separateQAbstractItemModel
subclass.Now in a table, all
item
s of aregister
should be layed out by having one column for eachcategory
, where a row corresponds with oneitem
.My issue now is - adding a new
category
inregister
doesn't go through theitem_model
, but instead through thecategory_model
, so I'm unsure how to add a column to theitem_model
.I can of course just override
insertColumns
like this:bool item_model::insertColumns(int column, int count, QModelIndex const& parent) { beginInsertColumns(parent, column, count); endInsertColumns(); return true; }
and then execute it like this:
category_model->insertRows(args); item_model->insertColumns(args);
But that seems completely nonsensical. My question is thus - how should I go about adding the columns to the item model?
-
@Folling said in How do deal with external changes to a model:
doesn't go through the item_model, but instead through the category_model
What are these models?
I can of course just override insertColumns like this:
No you can't. At the time
beginInsertColumns
is called,columnCount()
must return a number of columns inferior by exactlycount
to whencolumnCount()
is called afterendInsertColumns()
is executed. Also, the 3rd argument you are passing tobeginInsertColumns()
is just wrong, it should becolumn+count-1
-
What are these models?
They are subclasses of
QAbstractItemModel
that wrap around the specificitem
andcategory
objects to provide access to them in list and tableviews.No you can't. At the time beginInsertColumns is called, columnCount() must return a number of columns inferior by exactly count to when columnCount() is called after endInsertColumns() is executed.
Interesting - I didn't know that, however, in that case I could theoretically expose the two functions.
it should be column+count-1
Pardon me on that - I wrote the parameters out from my head, since I don't use that approach.
My current approach is to emit signals from
register
whenever acategory
is added, and connect that signal in myitem_model
. Speaking of that however - that would face the same issue as you mentioned before, given thatcolumnCount()
would return the same result prior and after - however it does work as of right now, so perhaps you were mistaken or it's working by accident. -
An update on this from my side:
My initial approach wasn't flawless, as @VRonin pointed out, because
QAbstractItemModel::columnCount
didn't return the appropriate values. I've fixed this, by not immediately passing the new count after inserting the elements to a list, of which the size was used, but instead have the model save exactly how many categories it currently accounts for, so the connection looks like this:connect(item_registry.get(), &item_registry::category_added, [this](int position, QSharedPointer<category>) { beginInsertColumns(QModelIndex{}, position, position); _current_category_count++; endInsertColumns(); });
and likewise
columnCount
:int item_model::columnCount(QModelIndex const&) const { if(!_register) { qCritical() << "Item-model didn't have a register"; return 0; } return 1 /* name */ + _current_category_count; }