Модель QStandardItemModel предназначена для определения широкого круга представлений - простых списков, таблиц и иерархических данных в виде деревьев. Каждый отдельный элемент в этой модели представлен типом QStandardItem.
В общем случае объект QStandardItemModel можно представить в виде таблицы. Для создания объекта модели в ее конструктор можно передать количество строк и столбцов:
QStandardItemModel(QObject *parent = nullptr) QStandardItemModel(int rows, int columns, QObject *parent = nullptr)
Например, определим модель из 3 строк и 2 столбцов:
QStandardItemModel model(3, 2); // 3 строки, 2 столбца std::cout << model.rowCount() << std::endl; // 3 std::cout << model.columnCount() << std::endl; // 2
Можно определить пустую модель и по ходу добавлять в нее строки и столбцы.
Для установки содержимого для определенной ячейки таблицы применяется метод setItem()
void setItem(int row, int column, QStandardItem *item) void setItem(int row, QStandardItem *item)
С каждой ячейкой таблицы ассоциируется определенный объект QStandardItem, который передается в метод в качестве последнего параметра. В конструктор класса QStandardItem можно передать непосредственно его содержимое в виде объекта QString:
QStandardItem(const QString &text)
Например, создание таблицы в QStandardItemModel:
#include <QApplication> #include <QStandardItemModel> int main(int argc, char *argv[]) { QApplication a(argc, argv); QStandardItemModel model(3, 2); // 3 строки, 2 столбца model.setItem(0, 0, new QStandardItem("Tom")); model.setItem(0, 1, new QStandardItem(39)); model.setItem(1, 0, new QStandardItem("Bob")); model.setItem(1, 1, new QStandardItem(43)); model.setItem(2, 0, new QStandardItem("Sam")); model.setItem(2, 1, new QStandardItem(28)); return a.exec(); }
В данном случае мы получим следующую условную таблицу, где условно первый столбец представляет имя человека, а второй - возраст:
Tom | 39 |
Bob | 43 |
Sam | 28 |
Для получения данных из модели применяется метод item(), в который передается номер строки и столбца и который возвращает объект QStandardItem:
QStandardItem *QStandardItemModel::item(int row, int column = 0)
Чтобы из QStandardItem получить сами данные, применяется метод data()
QVariant QStandardItem::data(int role = Qt::UserRole + 1) const
В этот метод надо передать роль. При работе с данными, которые предназначены для отображения/редактирования и представляют QString, применяются роли Qt::EditRole
и
Qt::DisplayRole
. Например, получим данные модели:
#include <QApplication> #include <QStandardItemModel> #include <iostream> int main(int argc, char *argv[]) { QApplication a(argc, argv); QStandardItemModel model(3, 2); model.setItem(0, 0, new QStandardItem(QString("Tom"))); model.setItem(0, 1, new QStandardItem(QString("39"))); model.setItem(1, 0, new QStandardItem(QString("Bob"))); model.setItem(1, 1, new QStandardItem(QString("43"))); model.setItem(2, 0, new QStandardItem(QString("Sam"))); model.setItem(2, 1, new QStandardItem(QString("28"))); for (int row = 0; row < model.rowCount(); ++row) { for (int column = 0; column < model.columnCount(); ++column) { std::cout << model.item(row, column)->data(Qt::DisplayRole).toString().toStdString() << "\t"; } std::cout << std::endl; } return a.exec(); }
Поскольку метод data()
возвращает значение QVariant, то для вывода на консоль полученное значение преобразуется сначала в QString, а затем в стандартную строку С++. Консольный вывод:
Tom 39 Bob 43 Sam 28
QStandardItemModel также удобно применять для создания иерархических структур данных для последующего отображения их в виде деревьев. В таких структурах данных одни элементы могут содержать другие элементы, а те - третьи элементы.
В QStandardItemModel для создания такой структуры данных сначала необходимо получить корневой узел с помощью метода invisibleRootItem()
QStandardItemModel model; // получаем корневой узел QStandardItem* parentItem = model.invisibleRootItem();
Метод возвращает указатель QStandardItem
, который по сути можно ассоциировать со всем деревом. Далее в этот элемент можно добавить другие элементы. Для этого применяется
метод appendRow(), в который передается добавляемый QStandardItem:
QStandardItemModel model; QStandardItem* parentItem = model.invisibleRootItem(); QStandardItem* languages = new QStandardItem("Языки программирования"); QStandardItem* databases = new QStandardItem("Базы данных"); parentItem->appendRow(languages); parentItem->appendRow(databases); languages->appendRow(new QStandardItem("C++")); languages->appendRow(new QStandardItem("Python")); databases->appendRow(new QStandardItem("MySQL")); databases->appendRow(new QStandardItem("PostgreSQL"));
Здесь в корневой узел добавляются два узла languages и databases, в которые, в свою очередь, добавляется по 2 новых элементов. То есть в итоге мы получим структуру типа следующей:
Например, получим всю иерархию узлов и выведем на консоль:
#include <QApplication> #include <QStandardItemModel> #include <iostream> void printItems(const QStandardItem* parent, int level = 0) { for(int i{};i<parent->rowCount(); i++) { for(int j{}; j < level; j++) { std::cout << " "; // для отделения дочерних узлов выводим пробелы } QStandardItem* item = parent->child(i, 0); std::cout << item->data(Qt::DisplayRole).toString().toStdString() << std::endl; printItems(item, level+1); } } int main(int argc, char *argv[]) { QApplication a(argc, argv); QStandardItemModel model; QStandardItem* parentItem = model.invisibleRootItem(); QStandardItem* languages = new QStandardItem("Languages"); QStandardItem* databases = new QStandardItem("Databases"); parentItem->appendRow(languages); parentItem->appendRow(databases); languages->appendRow(new QStandardItem("C++")); languages->appendRow(new QStandardItem("Python")); databases->appendRow(new QStandardItem("MySQL")); databases->appendRow(new QStandardItem("PostgreSQL")); printItems(parentItem); return a.exec(); }
Консольный вывод:
Languages C++ Python Databases MySQL PostgreSQL