如何使用 MV 在 Qt 模型中实现层次结构?
How to implement a hierarchical structure in a Qt model using MV?
我最近开始学习Qt,正在研究模型。
我有以下分层模型。
struct group{
QList<sample> samples;
QString name;
}
struct sample{
QString name;
}
有群组 - 群组列表。每组有几个样本。这样就完成了层次结构。
样本没有children,组没有parent。
但是这个层次结构确实给我带来了问题,我无法使用 qt mv QAbstractItemModel 实现它来像 TreeView 一样显示它。
在树中,作为根 - 我需要显示组的名称,作为叶 - 特定组的特定选择。
您可以在 QModelIndex::internalPointer
中存储指向 group
和 sample
对象的指针
适配this example,你得到
class GroupModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit GroupModel(QList<group> groups, QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
private:
QList<group> groups;
};
GroupModel::GroupModel(QList<group> groups, QObject *parent)
: QAbstractItemModel(parent), groups(groups)
{
}
QModelIndex GroupModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
if (!parent.isValid())
return createIndex(row, column, &groups[row]);
if (group * g = static_cast<group *>(parent.internalPointer()))
return createIndex(row, column, &g->samples[row]);
return QModelIndex();
}
QModelIndex GroupModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
void * p = index.internalPointer();
for (int i = 0; i < groups.count; ++i)
{
if (p == &groups[i]) return QModelIndex();
for (auto & s : groups[i]->samples)
{
if (p == &s) return createIndex(i, 0, &groups[i]);
}
}
return QModelIndex();
}
int GroupModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0)
return 0;
else if (!parent.isValid())
return groups.count()
else if (group * g = static_cast<group *>(parent.internalPointer()))
return g->samples.count();
}
int GroupModel::columnCount(const QModelIndex &parent) const
{
return 1;
}
QVariant GroupModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
if (!index.parent().isValid())
return static_cast<group *>(index.internalPointer())->name;
return static_cast<sample *>(index.internalPointer())->name;
}
QVariant GroupModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return "Name";
return QVariant();
}
我最近开始学习Qt,正在研究模型。
我有以下分层模型。
struct group{
QList<sample> samples;
QString name;
}
struct sample{
QString name;
}
有群组 - 群组列表。每组有几个样本。这样就完成了层次结构。
样本没有children,组没有parent。
但是这个层次结构确实给我带来了问题,我无法使用 qt mv QAbstractItemModel 实现它来像 TreeView 一样显示它。
在树中,作为根 - 我需要显示组的名称,作为叶 - 特定组的特定选择。
您可以在 QModelIndex::internalPointer
group
和 sample
对象的指针
适配this example,你得到
class GroupModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit GroupModel(QList<group> groups, QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
private:
QList<group> groups;
};
GroupModel::GroupModel(QList<group> groups, QObject *parent)
: QAbstractItemModel(parent), groups(groups)
{
}
QModelIndex GroupModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
if (!parent.isValid())
return createIndex(row, column, &groups[row]);
if (group * g = static_cast<group *>(parent.internalPointer()))
return createIndex(row, column, &g->samples[row]);
return QModelIndex();
}
QModelIndex GroupModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
void * p = index.internalPointer();
for (int i = 0; i < groups.count; ++i)
{
if (p == &groups[i]) return QModelIndex();
for (auto & s : groups[i]->samples)
{
if (p == &s) return createIndex(i, 0, &groups[i]);
}
}
return QModelIndex();
}
int GroupModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0)
return 0;
else if (!parent.isValid())
return groups.count()
else if (group * g = static_cast<group *>(parent.internalPointer()))
return g->samples.count();
}
int GroupModel::columnCount(const QModelIndex &parent) const
{
return 1;
}
QVariant GroupModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
if (!index.parent().isValid())
return static_cast<group *>(index.internalPointer())->name;
return static_cast<sample *>(index.internalPointer())->name;
}
QVariant GroupModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return "Name";
return QVariant();
}