Нет, вам не нужно переопределять эти функции.
Простой пример использования QSortFilterProxyModel ниже:
Model.hpp
#pragma once
#include <QAbstractListModel>
class Model : public QAbstractListModel {
Q_OBJECT
public:
enum Roles {
Name = Qt::UserRole + 1
};
Model(QObject* parent = nullptr);
virtual ~Model();
// QAbstractItemModel interface
int rowCount(const QModelIndex &parent) const noexcept override;
QVariant data(const QModelIndex &index, int role) const noexcept override;
QHash<int, QByteArray> roleNames() const noexcept override;
private:
QStringList list_;
};
model.cpp
#include "Model.hpp"
Model::Model(QObject *parent) : QAbstractListModel{parent}
{
list_ << "Adam" << "John" << "Alice" << "Kate";
}
Model::~Model()
{
}
int Model::rowCount(const QModelIndex &parent) const noexcept
{
return list_.size();
}
QVariant Model::data(const QModelIndex &index, int role) const noexcept
{
if(!index.isValid() || role < Name)
return QVariant{};
auto name = list_[index.row()];
if(role == Name)
return name;
return QVariant{};
}
QHash<int, QByteArray> Model::roleNames() const noexcept
{
return QHash<int, QByteArray>{{Name, "name"}};
}
FilterModel.hpp
#pragma once
#include <QSortFilterProxyModel>
class FilterModel : public QSortFilterProxyModel {
Q_OBJECT
public:
FilterModel(QObject* parent = nullptr);
virtual ~FilterModel();
Q_INVOKABLE void setFilterString(const QString& filter) noexcept;
};
FilterModel.cpp
#include "FilterModel.hpp"
#include "Model.hpp"
FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel{parent}
{
}
FilterModel::~FilterModel()
{
}
void FilterModel::setFilterString(const QString &filter) noexcept
{
setFilterCaseSensitivity(Qt::CaseInsensitive);
setFilterFixedString(filter);
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "Model.hpp"
#include "FilterModel.hpp"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Model model;
FilterModel filterModel;
filterModel.setSourceModel(&model);
filterModel.setFilterRole(Model::Name);
QQmlApplicationEngine engine;
QQmlContext* ctx = engine.rootContext();
ctx->setContextProperty("filterModel", &filterModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.11
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 200
height: 300
ColumnLayout {
anchors.fill: parent
TextField {
id: textField
Layout.fillWidth: true
placeholderText: "Search..."
onTextChanged: { filterModel.setFilterString(textField.text) }
}
ListView {
id: view
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
model: filterModel
delegate: Text {
width: parent.width
text: name
font.pointSize: 14
font.bold: true
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
}
Обратите внимание, если у вас есть пользовательский класс в качестве элемента модели, вы должны переопределить
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
для вашего фильтра.