Keeping filtered view up to date
-
Hi,
I have a widget that has a custom QAbstractTableModel that is proxied to a custom QSortFilterProxyModel. Widget displays orders coming from the exchange. There is a filter functionality on widget. For example, if you want to display orders only with state "New", you can do so via an input field provided on UI. The problem here is that when the state of the order changes (to "Filled" for example), the view is not kept up to date, i.e. orders with state "Filled" stays on the view. In order to filter "New" orders again, I have to apply filter again. What might be the problem here? Let me know if I should provide any code snippet for the solution.
-
@ozcanay
I believe you mean: you update a field in a row so that it should no longer be shown according to the currentQSortFilterProxyModel
filter setting? That should happen automatically when your base model emits thedataChanged()
signal, so that the view will know to re-evaluate whether that row should/should not be visible. Show your code if necessary. -
I am actually already doing what you said. In my BaseModel, when an an entry is updated I do:
emit dataChanged(index(row_index, 0), index(row_index, column_count_));
In the proxy model that proxies this base model I call a slot named
onSourceDataChanged
upondataChanged
signal emitted from the base model.void ProxyModel::onSourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles) { emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles); }
I connect this signal-slot relation in widget that displays the model:
QObject::connect(base_model, &BaseModel::dataChanged, proxy_model, &ProxyModel::onSourceDataChanged);
When I filter the view, I can see that the view is updated, some cells keep getting updated as well as the state. So, I believe I am emitting dataChanged signal as intended. However, filter is not respected.
-
@ozcanay
I don't know. Tryvoid QSortFilterProxyModel::invalidate()
to verify that updates.BTW, I may be wrong, but I would not expect to need your mapped signal. So far as I know, even if the view is connected through a proxy it will still correctly see source model changes/
dataChanged()
signals and act on them. Indeed, you might just try removing yourconnect(&ProxyModel::onSourceDataChanged)
to (a) verify and (b) just in case that is actaully interfering.So far as I recall, I used
QSortFilterProxyModel
with no extra code and views updated correctly. Unless anyone corrects me on this..... (I suppose it's possible I noticed sort changes correctly reflected but did not try filter ones.) -
@ozcanay said in Keeping filtered view up to date:
emit dataChanged(index(row_index, 0), index(row_index, column_count_));
This is wrong - index(row_index, column_count_) is invalid.
-
@Christian-Ehrlicher said in Keeping filtered view up to date:
This is wrong - index(row_index, column_count_) is invalid.
Funnily enough the changes @Christian-Ehrlicher implemented to the code of the views make it so the views will still update correctly. Unfortunately
QSortFilterProxyModel
is not as smart and will just do nothing if one of the indexes is invalid. i suspect it should beindex(row_index, column_count_-1)
-
What is invalid about it? Is it just the fact that
column_count_
should becolumn_count_ - 1
or is there something else as well? -
@ozcanay said in Keeping filtered view up to date:
Is it just the fact that column_count_ should be column_count_ - 1
correct
-
@VRonin said in Keeping filtered view up to date:
@Christian-Ehrlicher said in Keeping filtered view up to date:
This is wrong - index(row_index, column_count_) is invalid.
Funnily enough the changes @Christian-Ehrlicher implemented to the code of the views make it so the views will still update correctly. Unfortunately
QSortFilterProxyModel
is not as smart and will just do nothing if one of the indexes is invalid. i suspect it should beindex(row_index, column_count_-1)
Even though obviously what I have done is wrong, this still smells like a bug to me. I would expect uniform behavior from Qt.
-
@ozcanay If you pass mess in you will get mess out. Imo there will be even a warning message when your Qt libs build in debug mode.
-
When subclassing models, passing them through the model test is always advisable. Mistakes like this one are easily spotted by that tool