Reputation: 43
I recently started learning Qt and am studying models.
I have the following hierarchical model.
struct group{
QList<sample> samples;
QString name;
}
struct sample{
QString name;
}
There are groups - a list of groups. Each group has several samples. This completes the hierarchy.
The sample has no children, and the group has no parent.
But this hierarchy has really caused me problems and I cannot implement it using qt mv QAbstractItemModel to display it like TreeView.
In the tree, as a root - I need to display the name of the group, and as a leaf - a specific selection of a particular group.
Upvotes: 1
Views: 803
Reputation: 62531
You can store pointers to your group
and sample
objects in the QModelIndex::internalPointer
Adapting this example, you get
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();
}
Upvotes: 1