所以我有一个自定义的QAbstractItemModel,它重写了以下功能:
QVariant data(..) const;
QVariant headerData(..) const;
QModelIndex index(..) const;
QModelIndex parent(..) const;
int rowCount(..) const;
int columnCount(..) const;
virtual bool removeRows(..);
是否有必要在使用我的模型作为源的自定义QSortFilterProxyModel中重写所有这些方法?
我感到困惑的原因是该手册的摘录:
由于QAbstractProxyModel及其子类是从以下对象派生的 QAbstractItemModel,关于子类化法线的许多相同建议 模型也适用于代理模型。另外,值得注意的是 该类中许多函数的默认实现 被编写为使它们在相关 源模型。这种简单的代理机制可能需要重写 用于行为更复杂的源模型;例如,如果 源模型提供了一个自定义的hasChildren()实现,您 还应该在代理模型中提供一个。
https://doc.qt.io/archives/qt-4.8/qsortfilterproxymodel.html#subclassing
答案 0 :(得分:1)
否,您不需要覆盖这些功能。
简单示例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
过滤器。