当我开始问here时,我试图在不同的视图中以不同的方式查看Qt中单个模型中包含的数据,而无需创建更多模型且不更改它。
更具体一点:我试图采用QString并在几个表格中逐字显示,并在其他情况下将其视为简单的操作。
命名一个这样的操作:一个表将反转字符串(此表只有一行,但由于程序相关原因,行编辑不起作用)并删除任何空格(将保留在模型中,因为在其他视图中是必需的。)
编辑: 提供更完整,更具体的示例:Hello World - > Dlrow Olleh。 我想要反转大小写并检查完全由大写字母组成的单词 - 这些单词将完全保留为大写字母。
另一个计划的操作也删除了所有空格,但这次表格将是一个矩阵(所以我想要对索引函数进行一些更改)。
EDIT2:请注意,矩阵的大小会根据输入的大小而变化,以适应屏幕,因此索引(至少在表格本身中)不会保持不变。如果那很重要......
过去两天我一直试图弄清楚如何做到这一点,而且我能找到的最好的(除了阅读Qt文档之外,没有任何帮助)是 this article
但是,它并没有解释每一段代码的作用是否足够好,因此不允许像我这样不熟悉这个概念的人做出任何修改。代码以满足我的需求。当然,我可以创建更多的模型,并在凌乱的底层之外执行所有这些操作,但我喜欢挑战自己,尽可能多地学习一些东西,找到更好,更有效的方法来做事。
在对子类化时,我需要在QAbstractProxyModel中实现什么,更重要的是 - 我该怎么做(解释代码将非常感激) 为了创建一个会提供这种行为的代码? (我知道每个代理可能会有所不同)
答案 0 :(得分:1)
在您根据需要进行各种行为的必要测试用例修改问题之前,这里有一个简单的代理,它可以反转字符串值并删除所有空格:
class FlexibleProxy : public QIdentityProxyModel {
public:
enum {
StripSpaces = 0x1,
Reverse = 0x2
} Operation;
Q_DECLARE_FLAGS(Operations, Operation)
private:
Operations m_ops;
public:
FlexibleProxy(Operations ops, QObject * parent = 0) :
QIdentityProxyModel(parent), m_ops(ops) {}
QVariant data(QModelIndex & index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE {
auto val = QIdentityProxyModel::data(index, role);
if ((role == Qt::DisplayRole || role == Qt::EditRole)
&& val.userType() == QMetaType::QString) {
auto str = val.toString();
if (m_ops & StripSpaces) str.remove(QLatin1Char(' '));
if (m_ops & Reverse) reverse(str);
val.setValue(str);
}
return val;
}
};
Q_DECLARE_OPERATORS_FOR_FLAGS(FlexibleProxy::Operations)
static void reverse(QString & str) {
auto const size = str.size();
for (int i = 0; i <= size/2; ++i) {
std::swap(str[i], str[size-i]);
}
}
使用:
FlexibleProxy proxy{FlexibleProxy::Reverse | FlexibleProxy::StripSpaces};
proxy.setSourceModel(...);
view.setModel(&proxy);
答案 1 :(得分:1)
由于您不需要数据过滤(根据您的OP),您可以使用QIdentityProxyModel
。以下是所有类以及屏幕截图
mainwindow.cpp
#include "mainwindow.h"
#include "basemodel.h"
#include "identitymodel.h"
#include <QTableView>
#include <QBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget* cWidget = new QWidget(this);
setCentralWidget(cWidget);
IdentityModel* normalModel = new IdentityModel(IdentityModel::UnModified, cWidget);
IdentityModel* reverseModel = new IdentityModel(IdentityModel::Reverse, cWidget);
IdentityModel* noSpaceModel = new IdentityModel(IdentityModel::NoSpace, cWidget);
normalModel->setSourceModel(&BaseModel::instance());
reverseModel->setSourceModel(&BaseModel::instance());
noSpaceModel->setSourceModel(&BaseModel::instance());
QTableView* view1 = new QTableView(cWidget);
QTableView* view2 = new QTableView(cWidget);
QTableView* view3 = new QTableView(cWidget);
view1->setModel(normalModel);
view2->setModel(reverseModel);
view3->setModel(noSpaceModel);
QHBoxLayout* hLayout = new QHBoxLayout(cWidget);
hLayout->addWidget(view1);
hLayout->addWidget(view2);
hLayout->addWidget(view3);
}
basemodel.h
#ifndef BASEMODEL_H
#define BASEMODEL_H
#include <QStringListModel>
class BaseModel : public QStringListModel
{
Q_OBJECT
public:
static BaseModel& instance()
{
static BaseModel sInstance;
return sInstance;
}
virtual int rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
return m_dataList.size();
}
virtual QVariant data(const QModelIndex& modelIndex, int role) const;
signals:
public slots:
private:
explicit BaseModel(QObject* prnt=0);
QStringList m_dataList;
};
#endif // BASEMODEL_H
basemodel.cpp
#include "basemodel.h"
BaseModel::BaseModel(QObject* prnt)
: QStringListModel(prnt),
m_dataList({"Hello World", "Good Bye World"})
{
}
QVariant BaseModel::data(const QModelIndex& modelIndex, int role) const
{
if (modelIndex.isValid() && modelIndex.row() < m_dataList.size() && role == Qt::DisplayRole) {
return m_dataList.at(modelIndex.row());
}
return QVariant();
}
identitymodel.h
#define IDENTITYMODEL_H
#include <QIdentityProxyModel>
class IdentityModel : public QIdentityProxyModel
{
Q_OBJECT
public:
enum StringMod
{
UnModified,
Reverse,
NoSpace
};
explicit IdentityModel(StringMod mod, QObject* prnt=0);
virtual QVariant data(const QModelIndex& proxyIndex, int role) const;
signals:
public slots:
private:
StringMod m_stringMod;
};
identitymodel.cpp
#include "identitymodel.h"
#include <algorithm>
IdentityModel::IdentityModel(StringMod mod, QObject* prnt)
: QIdentityProxyModel(prnt),
m_stringMod(mod)
{
}
QVariant IdentityModel::data(const QModelIndex& proxyIndex, int role) const
{
QVariant dataToModify(QIdentityProxyModel::data(proxyIndex, role));
if (role == Qt::DisplayRole && m_stringMod != UnModified) {
QString str(dataToModify.toString());
if (m_stringMod == NoSpace)
return str.remove(' ');
else {
QByteArray ba(str.toUtf8());
std::reverse(ba.data(), ba.data() + str.length());
str = QString(ba);
}
return str;
}
return dataToModify;
}