Chilarai
Chilarai

Reputation: 1888

Create multiple instances of QSortFilterProxyModel for view

I have two listviews on a single Page component. The model for both is coming from a single QSortFilterProxyModel. The problem is if I set data for one ListView, the other one is also changed. This happens as there is a single instance of the model.

Will I have to create 2 different instances of the QSortFilterProxyModel or there is some other way around?

My Code

main.cpp


int main(int argc, char *argv[])
{

    // Application basic initialization
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    QtWebEngine::initialize();
    QQuickStyle::setStyle("Default");

    FilterModel filterModel;
    FilterList filterList;

    // Set contexts for QML
    engine.rootContext()->setContextProperty("filterModel",&filterModel);
    engine.rootContext()->setContextProperty("filterList",&filterList);


    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

filterlist.cpp

#include "filterlist.h"

FilterList::FilterList(QObject *parent) : QSortFilterProxyModel(parent)
{
    setSourceModel(&m_filterListModel);
}

void FilterList::searchByCategory(QString filterSubCategory)
{

    setFilterRole(m_filterListModel.FilterListCategoryRole);
    this->setFilterCaseSensitivity(Qt::CaseInsensitive);
    this->setFilterFixedString(filterSubCategory);
}

mypage.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.3

Page {

    id : somepageid

    Column{
        Button{
            id: btn1
            text: "btn a"
            onClicked: {
                filterList.searchByCategory("category a")
            }
        }

        Button{
            id: btn2
            text: "btn b"
            onClicked: {
                filterList.searchByCategory("category b")
            }
        }
    }

    ListView{
        id: lv1
        model: filterList
        height: 100
        delegate: Row{
            Text{
                text: name
            }
        }
    }

    ListView{
        id: lv2
        anchors.top: lv1.bottom
        model: filterList
        height: 100
        delegate: Row{
            Text{
                text: name
            }
        }
    }

}

Upvotes: 1

Views: 740

Answers (1)

Maxim Skvortsov
Maxim Skvortsov

Reputation: 435

Will I have to create 2 different instances of the QSortFilterProxyModel or there is some other way around?

Even if you create 2 instances of proxy models, you will experience the same problem if you set the same source for both. When you call QSortFilterProxyModel::setSource, it connects proxy model to source model and everything you change will be propagated to source model. So if you change something in 1st proxy model it will propagate to source model and from source model to 2nd proxy model.

Documentation citation QSortFilterProxyModel:

Any changes made through the QSortFilterProxyModel are applied to the original model.

So in order to have 2 independend lists with initially the same models, you have to create 2 instances of source model and 2 instances of the proxy model.

Upvotes: 3

Related Questions