Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.5.2
Description
If invalidate() is called earlier, then invalidateFilter() might not trigger reevaluation.
In the code below, the standard QSortFilterProxyModel behaves correctly and emits the signal, but a custom proxy model does not.
Code
#include <QCoreApplication> #include <QSortFilterProxyModel> #include <QStringListModel> #include <QTimer> #include <QDebug> class CustomProxyModel : public QSortFilterProxyModel { Q_OBJECT public: CustomProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent) {} void setFilter(const QString& s) { if (m_matchString == s) return; //rowCount(); // Workaround: Calling rowCount() here makes things work m_matchString = s; invalidateFilter(); } bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override { const auto index = sourceModel()->index(sourceRow, 0, sourceParent); if (!index.isValid()) return false; bool accepted = index.data().value<QString>() == m_matchString; qDebug() << '\t' << index.data() << "Accepted?" << accepted; return accepted; } private: QString m_matchString; }; int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QStringListModel model({"1", "2", "3", "4", "5"}); // ============================================== qDebug() << "=== Testing CustomProxyModel ==="; qDebug() << "Initializing..."; CustomProxyModel proxyModel; proxyModel.setFilter("X"); // Reject all source data at the start proxyModel.sort(0, Qt::AscendingOrder); // Trigger an evaluation proxyModel.setSourceModel(&model); qDebug() << "Invalidating..."; proxyModel.invalidate(); qDebug() << "Connnecting signal..."; QObject::connect(&proxyModel, &QSortFilterProxyModel::rowsInserted, &app, [&] { qDebug() << "SIGNAL EMITTED! CustomProxyModel's new rowCount():" << proxyModel.rowCount(); }); qDebug() << "Changing filter..."; proxyModel.setFilter("3"); // We expect to see a signal emitted here to learn that the proxy model now has 1 row // ============================================== qDebug() << ""; qDebug() << "=== Testing QSortFilterProxyModel ==="; qDebug() << "Initializing..."; QSortFilterProxyModel qsfpm; qsfpm.setFilterRegularExpression("X"); // Reject all source data at the start qsfpm.setSourceModel(&model); qDebug() << "Invalidating..."; qsfpm.invalidate(); qDebug() << "Connnecting signal..."; QObject::connect(&qsfpm, &QSortFilterProxyModel::rowsInserted, &app, [&] { qDebug() << "SIGNAL EMITTED! QSortFilterProxyModel's new rowCount():" << qsfpm.rowCount(); }); qDebug() << "Changing filter..."; qsfpm.setFilterRegularExpression("3"); // ============================================== } #include "main.moc"
Output
=== Testing CustomProxyModel === Initializing... QVariant(QString, "1") Accepted? false QVariant(QString, "2") Accepted? false QVariant(QString, "3") Accepted? false QVariant(QString, "4") Accepted? false QVariant(QString, "5") Accepted? false Invalidating... Connnecting signal... Changing filter... === Testing QSortFilterProxyModel === Initializing... Invalidating... Connnecting signal... Changing filter... SIGNAL EMITTED! QSortFilterProxyModel's new rowCount(): 1