forcing proxy model to update
-
Hi all -
I've implemented a QSortFilterProxyModel, intended for use in filtering model that I display via a QML GridView. I think I've got all the selection logic properly implemented in my override of the filterAcceptsRow() function, but I don't know how to cause it to reset when data in the model changes.
When the program starts up, the filterAcceptsRow() routine is called, but never again. When the model is populated with additional items, the proxy model doesn't seem to do anything.
I can post code if desired, but this is more of a general question. How does one get the proxy model to do whatever it needs to do in order for my QML display(s) to update?
Thanks...
-
Hi all -
I've implemented a QSortFilterProxyModel, intended for use in filtering model that I display via a QML GridView. I think I've got all the selection logic properly implemented in my override of the filterAcceptsRow() function, but I don't know how to cause it to reset when data in the model changes.
When the program starts up, the filterAcceptsRow() routine is called, but never again. When the model is populated with additional items, the proxy model doesn't seem to do anything.
I can post code if desired, but this is more of a general question. How does one get the proxy model to do whatever it needs to do in order for my QML display(s) to update?
Thanks...
-
@sierdzio thanks for the reply. The docs don't really say what the effect of invalidation is (at least, I didn't see anything) -- will this force QML updates?
As far as using it, I suppose I could connect my model's dataChanged() signal to the proxy model's invalidate() routine...is this what you had in mind? Thanks.
-
@sierdzio thanks for the reply. The docs don't really say what the effect of invalidation is (at least, I didn't see anything) -- will this force QML updates?
As far as using it, I suppose I could connect my model's dataChanged() signal to the proxy model's invalidate() routine...is this what you had in mind? Thanks.
@mzimmers
See https://doc.qt.io/qt-6/qsortfilterproxymodel.html#dynamicSortFilter-prop.dynamicSortFilter
default is true. (Start by verifying what that is on yours.) So QSFPM will already attach a slot to model'sdataChanged()
. I don't know whether it's clever enough to examine the parameters to determine whether sort or filter are affected and ignore if not, or just re-sorts/filters completely for simplicity. But either way (assuming dynamic is on) you ought not need to invalidate.This is all Qt model/view side. As you know I know nothing about QML. But intuitively I would have thought it would work with way model works/not make above description incorrect.
-
@mzimmers
See https://doc.qt.io/qt-6/qsortfilterproxymodel.html#dynamicSortFilter-prop.dynamicSortFilter
default is true. (Start by verifying what that is on yours.) So QSFPM will already attach a slot to model'sdataChanged()
. I don't know whether it's clever enough to examine the parameters to determine whether sort or filter are affected and ignore if not, or just re-sorts/filters completely for simplicity. But either way (assuming dynamic is on) you ought not need to invalidate.This is all Qt model/view side. As you know I know nothing about QML. But intuitively I would have thought it would work with way model works/not make above description incorrect.
@JonB yeah, I noticed that, too. I'm going to play with it, though, to see if I can get something to happen.
I'm fairly sure I've got the signaling to QML working correctly, because without the filter, my model date is appropriately updated in the UI. So, it must be something in the proxy model I'm missing.
BTW: I see that QAbstractProxyModel has a sourceModel property. I'd like to use this, but I'm not familiar with using properties within C++. Do you happen to know how I'd go about accessing this from my proxy model?
EDIT: I guess I can access it through Q_PROPERTY, just as I would with QML.
EDIT 2: It turns out that the Q_PROPERTY didn't really bring anything to the party; you can't use it until you set it, and you can't set it until you know what it is. I'm just passing in the source model to the c'tor of the proxy model -- seems to work fine. -
M mzimmers has marked this topic as solved on
-
M mzimmers has marked this topic as unsolved on
-
@JonB yeah, I noticed that, too. I'm going to play with it, though, to see if I can get something to happen.
I'm fairly sure I've got the signaling to QML working correctly, because without the filter, my model date is appropriately updated in the UI. So, it must be something in the proxy model I'm missing.
BTW: I see that QAbstractProxyModel has a sourceModel property. I'd like to use this, but I'm not familiar with using properties within C++. Do you happen to know how I'd go about accessing this from my proxy model?
EDIT: I guess I can access it through Q_PROPERTY, just as I would with QML.
EDIT 2: It turns out that the Q_PROPERTY didn't really bring anything to the party; you can't use it until you set it, and you can't set it until you know what it is. I'm just passing in the source model to the c'tor of the proxy model -- seems to work fine.Well...it's working now, without my having to use the invalidate() method. Not sure what I changed, but here's the relevant code:
// qml ListView { id: spaceRow model: spaceModel delegate: TabButton { contentItem: Text { text: name MouseArea { anchors.fill: parent onClicked: { spaceRow.currentIndex = index equipmentProxyModel.setSpaceIndex(index) // c++ void EquipmentProxyModel::setSpaceIndex(int index) { m_spaceIndex = index; }
m_spaceIndex is used here:
bool EquipmentProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool rc = false; QModelIndex qmi = createIndex(sourceRow, 0); QUuid equipmentUuid = m_equipmentModel->data(qmi, m_equipmentModel->UuidRole).toUuid(); QUuid spaceUuid = m_spaceModel->getUuid(m_spaceIndex); if (m_spaceIndex == 0) { // all spaces rc = true; } else if (equipmentUuid.isNull()) { // don't bother } else { rc = m_spaceModel->equipmentInSpace(spaceUuid, equipmentUuid); } return rc; }
And this seems to suffice. Thanks to everyone who replied...
EDIT:
And...just like that, it stopped working (after some changes to the model. I followed the advice of @sierdzio and (re)inserted the invalidate() call:void EquipmentProxyModel::setSpaceIndex(int index) { m_spaceIndex = index; invalidate(); }
And now it works. No idea how I got it to work (temporarily) without this...
-
M mzimmers has marked this topic as solved on