所以我有一个覆盖以下函数的自定义 QAbstractItemModel:
QVariant data(..) const;
QVariant headerData(..) const;
QModelIndex index(..) const;
QModelIndex parent(..) const;
int rowCount(..) const;
int columnCount(..) const;
virtual bool removeRows(..);
是否有必要在使用我的模型作为源的自定义 QSortFilterProxyModel 中覆盖所有这些?
我困惑的根源是手册中的这段摘录:
Since QAbstractProxyModel and its subclasses are derived from QAbstractItemModel, much of the same advice about subclassing normal models also applies to proxy models. In addition, it is worth noting that many of the default implementations of functions in this class are written so that they call the equivalent functions in the relevant source model. This simple proxying mechanism may need to be overridden for source models with more complex behavior; for example, if the source model provides a custom hasChildren() implementation, you should also provide one in the proxy model.
https://doc.qt.io/archives/qt-4.8/qsortfilterproxymodel.html#subclassing
最佳答案
不,您不需要重写这些函数。
下面是 QSortFilterProxyModel 用法的简单示例:
模型.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_;
};
模型.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"}};
}
过滤模型.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;
};
过滤模型.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);
}
主要.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();
}
主.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
为您的过滤器。
关于c++ - 使用自定义 QSortFilterProxyModel 覆盖哪些函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55141141/