如何根据模型设置的视图调整模型?



情况

我有一个单一的Qt模型,特别是一个StringModel,它派生自QStringListModel,称为"model"。

我有三个观点,特别是三个QListViews,分别称为"listView_1","listView_2"和"listView_3"。

所有这三个 QListViews 都设置为一个模型,即:

(ui->listView_1)->setModel(model);
(ui->listView_2)->setModel(model);
(ui->listView_3)->setModel(model);

并发症

虽然我希望所有三个视图都引用相同的模型,但它们从该模型显示的数据应该略有不同。模型中指示在视图中显示哪些数据的函数是从 QStringListModel 继承的"data"成员函数,定义为:

QVariant StringModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()){
return QVariant();
}
if (role == Qt::DisplayRole)
{
int col = index.column();
int row = index.row();
if (col == 0){
QList<Contact*> list = contactList.findChildren<Contact*>();
return list.at(row)->toString();//<<THIS STATEMENT MUST BE VARIABLE
}
}
QVariant v;
return v;
}

上面代码中的第 12 行返回要在视图上显示的数据,这就是我想根据视图而变化的 return 语句。

问题

模型视图控制器最佳实践指出,我们应该能够保持模型相同,并使用微小的调整来更改视图。因此,如果不为 3 个视图定义 3 个模型,我将如何调整我的数据函数以根据它设置的视图返回不同的语句?或者,用一句话总结一下,如何根据模型设置的视图调整模型?

对于简单的用例,我建议使用QIdentityProxyModel.下面是一个包含两个视图的小示例,其中一个视图以相反的顺序显示字符串。

您必须仔细考虑Qt::ItemDataRole::EditRoleQt::ItemDataRole::DisplayRole这两个角色,以使其正常工作。

主.cpp

#include <cmath>
#include <QApplication>
#include <QHBoxLayout>
#include <QStandardItemModel>
#include "ReverseModel.h"
#include <QListView>
#include <QFrame>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto frame = new QFrame;
auto model = new QStandardItemModel;
auto view1 = new QListView;
auto view2 = new QListView;
view1->setModel(model);
auto reverseModel = new ReverseModel;
reverseModel->setSourceModel(model);
view2->setModel(reverseModel);
frame->setLayout(new QHBoxLayout);
frame->layout()->addWidget(view1);
frame->layout()->addWidget(view2);
model->appendRow(new QStandardItem("Test"));
frame->show();
return a.exec();
}

反向模型.h

#pragma once
#include <QIdentityProxyModel>
#include <algorithm>
class ReverseModel : public QIdentityProxyModel {
Q_OBJECT
public: 
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override {
if (role == Qt::DisplayRole || role==Qt::EditRole) {
auto data = QIdentityProxyModel::data(index);
auto string = data.toString();
std::reverse(string.begin(), string.end());
return string;
}
else {
return QIdentityProxyModel::data(index, role);
}
}
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override {
if (role == Qt::EditRole ) {
auto string = value.toString();
std::reverse(string.begin(), string.end());
QVariant reversedValue =string;
return QIdentityProxyModel::setData(index, reversedValue, role);
}
else {
return QIdentityProxyModel::setData(index, value, role);
}
}
};

最新更新