使用自定义QSortFilterProxyModel覆盖哪些函数

时间:2019-03-13 11:45:24

标签: c++ qt proxy model qt4.8

所以我有一个自定义的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

1 个答案:

答案 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

过滤器。