Модель QStandardItemModel

Последнее обновление: 12.01.2024

Модель 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();
}

В данном случае мы получим следующую условную таблицу, где условно первый столбец представляет имя человека, а второй - возраст:

Tom39
Bob43
Sam28

Для получения данных из модели применяется метод 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 новых элементов. То есть в итоге мы получим структуру типа следующей:

Иерархические данные и QStandardItemModel в Qt

Например, получим всю иерархию узлов и выведем на консоль:

#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
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850