qt - 使用 QSortFilterProxyModel
问题描述
请查看以下代码:
CMyModel* myModel = new CMyModel(); //This is my main model sub-classing QAbstractListItemModel
CMySortModel* mySortModel = new CMySortModel(); //This is my sort filter proxy model sub-classing QSortFilterProxyModel
mySortModel->setSourceModel(myModel);
mySortModel->setDynamicSortFilter(true);
mySortModel->setSortRole(CMyModel::displayRole);
myModel->Initialize(); // This is working fine
mySortModel->sort(0);
// myModel->Initialize(); // This is not working
当数据结构(基本上是链接到CMyModel的整数的 QList )在调用mySortModel->sort(0)之前初始化时,上面的代码工作正常。
如果在 sort 方法调用之后初始化列表,则视图基本上不显示任何数据。
然后我尝试了以下
mySortModel->sort(0);
myModel->Initialize();
mySortModel->Invalidate(); // This is working fine.
但是意识到,每次 QList 中有更新时,我都需要调用mySortModel->Invalidate()来更新我的视图。否则视图不会更新。这导致完整的视图更新,进而在我的屏幕上闪烁。
由于对 Qt/QML 模型视图编码的想法不多,所以有点卡住了这个问题。
请纠正我,如果我做错了什么。
我的模型.cpp
#include "MyModel.h"
#include <QDateTime>
CMyModel::CMyModel(QObject *parent)
: QAbstractListModel(parent)
{
m_mapRoles.insert(rolesEnum::displayRole, "displayRole");
}
void CMyModel::Initialize()
{
qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
quint32 index = 0;
while (index < 200)
{
m_lstOfInts.append(qrand() % 1000);
index++;
}
}
int CMyModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_lstOfInts.count();
}
int CMyModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 1;
}
QVariant CMyModel::data(const QModelIndex &index, int role) const
{
Q_UNUSED(role)
int rowVal = index.row();
if (role == rolesEnum::displayRole)
{
if (rowVal >= 0 && rowVal < m_lstOfInts.count())
{
return m_lstOfInts.at(rowVal);
}
}
return QVariant();
}
QHash<int, QByteArray> CMyModel::roleNames() const
{
return m_mapRoles;
}
我的模型.h
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QAbstractListModel>
#include <QObject>
#include <QHash>
class CMyModel : public QAbstractListModel
{
Q_OBJECT
public:
enum rolesEnum {
displayRole
};
Q_ENUM(rolesEnum)
public:
explicit CMyModel(QObject *parent = NULL);
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
private:
QList<int> m_lstOfInts;
QHash<int, QByteArray> m_mapRoles;
// QAbstractItemModel interface
public:
QHash<int, QByteArray> roleNames() const;
void Initialize();
};
#endif // MYMODEL_H
我的排序模型.cpp
#include "MySortModel.h"
#include "MyModel.h"
CMySortModel::CMySortModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
bool CMySortModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
return sourceModel()->data(source_left, CMyModel::displayRole).toInt() < sourceModel()->data(source_right, CMyModel::displayRole).toInt();
}
MySortModel.h
#ifndef MYSORTMODEL_H
#define MYSORTMODEL_H
#include <QSortFilterProxyModel>
class CMySortModel : public QSortFilterProxyModel
{
public:
explicit CMySortModel(QObject* parent = NULL);
// QSortFilterProxyModel interface
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
};
#endif // MYSORTMODEL_H
主文件
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include "MyModel.h"
#include "MySortModel.h"
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterType<CMySortModel>("CMySortModel", 1, 0, "CMySortModel");
CMyModel* myModel = new CMyModel();
CMySortModel* mySortModel = new CMySortModel();
mySortModel->setSourceModel(myModel);
mySortModel->setDynamicSortFilter(true);
mySortModel->setSortRole(CMyModel::displayRole);
// myModel->Initialize(); // This works
mySortModel->sort(0);
myModel->Initialize(); // This works when followed by a invalidate call on the proxy model
mySortModel->invalidate();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("_myModel", mySortModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
{
delete mySortModel;
mySortModel = NULL;
delete myModel;
myModel = NULL;
return -1;
}
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0
Window {
id: window
visible: true
width: 800
height: 480
title: qsTr("Hello World")
ScrollView {
anchors.fill: parent
width: parent.width
GridView {
anchors.fill: parent
//columns: 2
model: _myModel
delegate: Text {
id: _text
text: model.displayRole
}
}
}
}
修改 Initialize 方法如下,现在可以使用
void CMyModel::Initialize()
{
qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
quint32 index = 0;
while (index < 200)
{
beginInsertRows(QModelIndex(), m_lstOfInts.size(), m_lstOfInts.size());
m_lstOfInts.append(qrand() % 1000);
index++;
endInsertRows();
}
}
解决方案
推荐阅读
- javascript - 打字时如何在每个可选位置自动插入分号?
- c - 当结构按值传递给函数时,结构内的指针似乎发生了变化
- python - 编码按钮 Yandex POST 数据
- rust - 如何在编译期间从 Rust 中的字符串文字中删除空格?
- flask - 谷歌云运行突然流量峰值错误
- c++ - 卡在正确地从 txt 文件中读取凭据
- javascript - 获取 shadow DOM 的 document.body/html
- android - 如何将撰写预览导出为 png/jpg
- prestashop - prestashop 1.7.8.0 polyfill-intl-normalizer 中的错误更新
- python - 怎么解决
Python中的错误?