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

标签 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 中覆盖所有这些?

我困惑的根源是手册中的这段摘录:

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/

相关文章:

ajax - AJAX 和 Azure 反向代理的 CORS 问题

c++ - 链接的外部 DLL 中 std::vector 的 Mex 动态内存管理问题;段错误

c++ - Qt 的 pragma 指令

c++ - template 模板类,如果存在就调用一个函数

c++ - 评论中的字符是什么意思?

c++ - 如何使用 QxtGlobalShortcut 库检测 Qt 中的按键释放事件

docker - Centos -- Yum 更新错误 - “HTTP Error 403 - Forbidden”

python-3.x - 如何通过 Selenium 在 Chrome 浏览器中使用 Tor

c++ - 使用 const 指针打印双链表

c++ - 实现windows窗体c++选项卡选择事件