c++ - 如何使用 QAbstractItemModel 映射多级对象模型
问题描述
我开始学习 Qt 中的 MVC 模式。
我有简单的数据结构,如下所示:
class Stage
{
public:
QString name;
int number;
};
class Doc
{
public:
Doc();
~Doc();
QString name;
int number;
QList<Stage *> *stages;
};
我想在 TreeView 中查看这个结构。为此,我创建了模型类:
class Model: public QAbstractItemModel
{
Q_OBJECT
public:
Model(QObject *parent);
~Model();
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
private:
QList<Doc*> *docs;
如果我只有一级数据(没有阶段的文档),一切正常,但我不明白如何将第二个树级别添加到模型(阶段)?
代码示例(一级)
Model::Model(QObject *parent) : QAbstractItemModel(parent)
{
docs = new QList<Doc*>();
for (int i = 0; i < 3; ++i) {
Doc *d = new Doc();
d->name = "name_" + QString::number(i);
d->number = i;
docs->append(d);
}
}
Model::~Model()
{
delete docs;
}
QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
if (!parent.isValid()) {
Doc *d = docs->at(row);
return createIndex(row, column, d);
}
return QModelIndex();
}
QModelIndex Model::parent(const QModelIndex &index) const
{
return QModelIndex();
}
int Model::rowCount(const QModelIndex &parent) const
{
int cnt = 0;
if (!parent.isValid()) {
cnt = docs->size();
}
return cnt;
}
int Model::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 3;
}
Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
if (!index.isValid())
return nullptr;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("Number");
case 1:
return tr("Code");
case 2:
return tr("Stages count");
default:
return QVariant();
}
}
return QVariant();
}
QVariant Model::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
{
Doc *d = static_cast<Doc*>(index.internalPointer());
switch (index.column()) {
case 0:
return d->name;
case 1:
return d->number;
case 2:
return d->stages->size();
default:
break;
}
}
return QVariant();
}
我认为它看起来像这样:
Model::Model(QObject *parent) : QAbstractItemModel(parent)
{
docs = new QList<Doc*>();
for (int i = 0; i < 3; ++i) {
Doc *d = new Doc();
d->name = "name_" + QString::number(i);
d->number = i;
for (int j = 5; j < 9; ++j) {
Stage *s = new Stage();
s->name = "name_" + QString::number(j);
s->number = j;
d->stages->append(s);
}
docs->append(d);
}
}
QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
if (!parent.isValid()) {
Doc *d = docs->at(row);
return createIndex(row, column, d);
} else {
Stage *s = static_cast<Doc*>(parent.internalPointer())->stages->at(row);
return createIndex(row, column, s);
}
return QModelIndex();
}
QModelIndex Model::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
else if (index.parent().isValid())
return createIndex(index.parent().row(), 0, index.internalPointer());
return QModelIndex();
}
int Model::rowCount(const QModelIndex &parent) const
{
int cnt = 0;
if (!parent.isValid()) {
cnt = docs->size();
} else {
cnt = static_cast<Doc*>(parent.parent().internalPointer())->stages->size();
}
return cnt;
}
但它的错误代码......
解决方案
推荐阅读
- ios - 进度条 SetProgres
- r - 考虑到控制变量,匹配 R 中的多个数据
- python - PatsyError:错误评估因素:NameError:由于列名中的特殊字符而未定义名称''回归
- discord.js - 我试图找到这个问题的答案,但我没有找到任何答案。我在 Visual Studio Code v1.50.1 上安装 quick.db 时遇到问题
- javascript - 当添加许多列表时,页面会被遮挡。我该如何解决?
- r - 如何在 r 中的列表上应用特定功能?
- karate - 空手道在graphql中替换
- python - 如何在参数解析器中传递文件夹图像目录的路径来测试我的文件夹中的所有图像,而不是只测试一个?
- python - 我正在返回一个 defaultdict(list),但在两者之间随机选择,为什么有时它什么也不返回?
- javascript - 如何在不为每个输入使用不同 id 标签的情况下使用 for 循环?