How to select the role of a QSortFilterProxyModel from QML?
-
I have a subclass of
QSortFilterProxyModel
to enable myComboBox
to filter records. Below is the code I currently have:filter.hpp:
#ifndef FILTER_H #define FILTER_H #include <QObject> #include <QSortFilterProxyModel> class CustomProxyModel : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged) public: explicit CustomProxyModel(QObject *parent = nullptr); private: QString m_filterText = ""; signals: void filterTextChanged(); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; public: QString filterText() const; void setFilterText(const QString &text); }; #endif // FILTER_H
filter.cpp:
QString CustomProxyModel::filterText() const { return m_filterText; } void CustomProxyModel::setFilterText(const QString &text) { if (m_filterText != text) { m_filterText = text; emit filterTextChanged(); invalidateFilter(); // Reapply the filter } } bool CustomProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { if (m_filterText.isEmpty()) { return true; // Accept all rows if no filter text is set } QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); QVariant data = sourceModel()->data(index); qDebug() << "Data for filtering:" << data << "Type:" << data.typeName(); return data.toString().contains(m_filterText, Qt::CaseInsensitive); }
Additionally, here is the QML code I am using:
ApplicationWindow { width: 300 height: 500 ListModel { id: myListModel // My elements have multiple roles: ListElement { id: 1; name: "Alice" } ListElement { id: 2; name: "Bob" } ListElement { id: 3; name: "Charlie" } } // Registered C++ type: CustomProxyModel { id: proxyModel sourceModel: myListModel // How to set role? filterString: "Alice" } ComboBox { anchors.fill: parent model: proxyModel textRole: "name" } }
The problem I’m facing is that I cannot figure out how to set the textRole that the
QSortFilterProxyModel
should use for filtering. Currently, it filters based on the first role, which is id (a number). However, I want it to filter based on the name role (a string). How can I achieve this? -
Try something like this. Use the data method of index.
bool CustomProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
const QModelIndex sourceIndex = sourceModel()->index(source_row, 0, source_parent);
// Some how get the the role you require.
const QString filterElement = sourceIndex.data(role).toString();
return(filterElement.toLower().startsWith(m_filterText));
}