qt — модель C ++ для QML TreeView

Из-за отсутствия какой-либо другой демонстрации Qt, я использую виджеты Qt SimpleTreeModelдемонстрация для реализации модели C ++ для моего QML TreeView. Я определил роли, чтобы QML мог их использовать, но у меня возникли проблемы с подключением их к фактическим данным модели.

Что мне также интересно, так это то, что демо widgets (C ++) работает нормально, но TreeModelпохоже, не хранит данные как переменную-член .. оставляет меня почесывать голову. Я понял это, каждый TreeItem хранит все свои дочерние элементы, и TreeModel имеет только один rootItem который в свою очередь хранит все данные как его дочерний элемент.

Класс TreeItem

class TreeItem
{
public:
explicit TreeItem(const QList<QVariant> &data, TreeItem *parentItem = 0);
~TreeItem();

void appendChild(TreeItem *child);

TreeItem *child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
int row() const;
TreeItem *parentItem();

private:
QList<TreeItem*> m_childItems;
QList<QVariant> m_itemData;
TreeItem *m_parentItem;
};

Класс TreeModel

class TreeModel : public QAbstractItemModel
{
Q_OBJECT

public:
enum DisplayRoles {
TitleRole = Qt::UserRole + 1,
SummaryRole
};

explicit TreeModel(const QString &data, QObject *parent = 0);
~TreeModel();

QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;

QHash<int, QByteArray> TreeModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[TitleRole] = "title";
roles[SummaryRole] = "summary";
return roles;
}private:
void setupModelData(const QStringList &lines, TreeItem *parent);

TreeItem *rootItem;
};

Модель загружает данные из default.txt

TreeModel::TreeModel(const QString &data, QObject *parent)
: QAbstractItemModel(parent)
{
QList<QVariant> rootData;
rootData << "Title" << "Summary";
rootItem = new TreeItem(rootData);
setupModelData(data.split(QString("\n")), rootItem);
}

void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
{
QList<TreeItem*> parents;
QList<int> indentations;
parents << parent;
indentations << 0;

int number = 0;

while (number < lines.count()) {
int position = 0;
while (position < lines[number].length()) {
if (lines[number].mid(position, 1) != " ")
break;
position++;
}

QString lineData = lines[number].mid(position).trimmed();

if (!lineData.isEmpty()) {
// Read the column data from the rest of the line.
QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts);
QList<QVariant> columnData;
for (int column = 0; column < columnStrings.count(); ++column)
columnData << columnStrings[column];

if (position > indentations.last()) {
// The last child of the current parent is now the new parent
// unless the current parent has no children.

if (parents.last()->childCount() > 0) {
parents << parents.last()->child(parents.last()->childCount()-1);
indentations << position;
}
} else {
while (position < indentations.last() && parents.count() > 0) {
parents.pop_back();
indentations.pop_back();
}
}

// Append a new item to the current parent's list of children.
parents.last()->appendChild(new TreeItem(columnData, parents.last()));
}

++number;
}
}

Моя проблема в этой функции, как мне связать роли с данными, которые хранятся в rootItem?. Заметка titleString а также summaryStringВозможны предложенные функции (при необходимости), но я не знаю, что в них написать, получить доступ к данным!

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();

if (index.isValid() && role >= TitleRole) {
switch (role) {
case TitleRole:
return QVariant(titleString(rootItem(index))); // get title through rootItem?
case SummaryRole:
return QVariant(summaryString(rootItem(index))); // get summary through rootItem?
}
}

if (role != Qt::DisplayRole)
return QVariant();

TreeItem *item = static_cast<TreeItem*>(index.internalPointer());

return item->data(index.column());
}

default.txtсодержит следующие данные, но то же самое доступно и в самой демонстрации Qt Creator.

Getting Started             How to familiarize yourself with Qt Designer
Launching Designer          Running the Qt Designer application
The User Interface          How to interact with Qt Designer

Designing a Component           Creating a GUI for your application
Creating a Dialog           How to create a dialog
Composing the Dialog        Putting widgets into the dialog example
Creating a Layout           Arranging widgets on a form
Signal and Slot Connections     Making widget communicate with each other

Using a Component in Your Application   Generating code from forms
The Direct Approach         Using a form without any adjustments
The Single Inheritance Approach Subclassing a form's base class
The Multiple Inheritance Approach   Subclassing the form itself
Automatic Connections       Connecting widgets using a naming scheme
A Dialog Without Auto-Connect   How to connect widgets without a naming scheme
A Dialog With Auto-Connect  Using automatic connections

Form Editing Mode           How to edit a form in Qt Designer
Managing Forms          Loading and saving forms
Editing a Form          Basic editing techniques
The Property Editor         Changing widget properties
The Object Inspector        Examining the hierarchy of objects on a form
Layouts             Objects that arrange widgets on a form
Applying and Breaking Layouts   Managing widgets in layouts
Horizontal and Vertical Layouts Standard row and column layouts
The Grid Layout         Arranging widgets in a matrix
Previewing Forms            Checking that the design works

Using Containers            How to group widgets together
General Features            Common container features
Frames              QFrame
Group Boxes             QGroupBox
Stacked Widgets         QStackedWidget
Tab Widgets             QTabWidget
Toolbox Widgets         QToolBox

Connection Editing Mode         Connecting widgets together with signals and slots
Connecting Objects          Making connections in Qt Designer
Editing Connections         Changing existing connections

Мой вывод показывает то же количество строк, что и в демонстрации виджетов, за исключением того, что нет текста. Кажется, что это просто не связано с ролями должным образом или роли не связаны с днем. Я прилагаю снимок экрана моего вывода.

введите описание изображения здесь

2

Решение

Точно так же, если кто-то пытается сделать то же самое, я понял это, и вот ответ. Метод данных модели должен читать следующее.

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();

TreeItem *item = static_cast<TreeItem*>(index.internalPointer());

if (index.isValid() && role >= TitleRole) {
switch (role) {
case TitleRole:
return item->data(0);
case SummaryRole:
return item->data(1);
}
}

if (role != Qt::DisplayRole)
return QVariant();

return item->data(index.column());
}

TreeItem может быть изменено в реальном приложении для хранения конкретных данных, и в этом случае вышеуказанный метод будет указывать на эти данные вместо подхода с использованием номера столбца.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]