Skip to content
wel.org.ua
wel.org.ua

  • Новини
  • Криптовалюта
  • Додатки
  • iT
  • Штучний інтелект
  • Статті
wel.org.ua

[:ru]Беседы о Qt: Парадигма Model-View[:]

Наталія Кравець, 16.04.202428.06.2025
[:ru]

Можно рассматривать модель как средство предоставления данных некоторым образом, а вид — как средство их отображения. Например, есть стандартная модель для списка строк — QStringListModel. А также есть модель, отражающая содержимое файловой системы, -QDirModel. QStandardItemModel — это многофункциональная модель. С последним классом мы и будем разбираться. Вот простейший пример использования этой модели — строим на ее основе список строк:

QStandardltemModel *model = new QStandardItemModel (this);   model->appendRow (new QStandardltem («one»)); model->appendRow (new QStandardItem («two»)); model->appendRow (new QStandardltem («three»)); model->appendRow (new QStandardItem («four»));   QTreeView *tv = new QTreeView (this); tv->setModel (model);

Итак, вначале создается экземпляр модели, затем в нее добавляются четыре элемента со строковыми значениями one, two, three, four. После этого создается виджет отображения модели (экземпляр QTreeView) и модель назначается ему. Обратите внимание: вместо QTreeView можно использовать и другой виджет представления — QListView:

QListView *lv = new QListView (this);

lv->setModel (model);

Разница — в том, что QListView не умеет отображать сложные списки (например, деревья или состоящие из нескольких колонок). Зато в QListView есть два режима отображения: обычным списком строк и в виде иконок. Но вернемся к модели и посмотрим на вызов функции:

model->appendRow (new QStandardltem ("one"));

Функция appendRow() добавляет в модель новый ряд с элементом, переданным в качестве параметра. Можно передать несколько элементов — список, — таким образом создается ряд с несколькими колонками.

Пример:

Замечу, что это следует отображать в QTreeView. Пример у нас — весьма упрощенный. Что будет, если требуется особо оформить каждый элемент, например первую колонку выводить жирным шрифтом?

QList items;

QStandardltem *item = new QStandardItem («column 0»);

QFont f = item->font(); f.setBold (true); item->setFont(f); items. append (item);

items.append (new QStandardItem («column 1»)); items.append (new QStandardItem («column 2»));

model->appendRow (items);

Как видно, с экземпляром QStandardltem можно проделывать разные интересные вещи: менять его шрифт, цвет, устанавливать флаги доступа:

item->setFlags (Qt:: ItemIsSelectable | Qt:: ItemIsEnabled);

В этом примере мы разрешаем выделение элемента. Можем и запретить, не указывая флаг Qt::ItemIsSelectable. QStandardltem оснащен теми же методами, что и модель — в него тоже добавляются ряды и колонки. Давайте создадим вложенный элемент для первой колонки:

Итак, вызовом:

item->appendRow (new QStandardItem («subitem 0»));

мы добавляем новый элемент subitem 0 как ряд к элементу item. В свою очередь к новосозданному элементу тоже можно добавлять элементы — так получается древовидная иерархия. Вот еще одна, более классическая иерархия — два корневых элемента, у каждого из которых есть внутренние элементы:

QStandardItem *item = new QStandardItem («animals»); item->appendRow (new QStandardItem («dog»)); item->appendRow (new QStandardItem («cat»)); item->appendRow (new QStandardItem («cow»)); model->appendRow (item);

item = new QStandardItem («games»); item->appendRow (new QStandardItem («Fallout»)); item->appendRow (new QStandardItem («Doom»)); item->appendRow (new QStandardItem («Quake»)); model->appendRow (item);

Экземпляры QStandardItem весьма универсальны, и в большинстве случаев нет нужды создавать свои классы для представления элементов. Объект QStandardItem может содержать текст, иконку или checkbox. Как уже сообщалось, у такого объекта можно менять значения свойств вроде цвета, шрифта.

С созданием и наполнением модели мы немного разобрались. Теперь посмотрим, как получать данные — например, выделенный элемент и тому подобное.

Во-первых, научимся получать из модели нужные нам элементы. Для «плоского» списка строк сделать это довольно просто: достаточно обратиться к функции QStandardItemModel::findItems(), которая возвращает список элементов, текст коих соответствует заданному вами критерию.

В примере ниже мы получаем такой список (критерий — текст column 1), проходим по нему в цикле и выводим текст найденных элементов:
QList list = model->findItems («column 1», J Qt::MatchExactly | Qt::MatchRecursive);

foreach (QStandardItem *item, list) qDebug() << item->text();

Обратите внимание на флаг Qt::MatchRecursive. Он указывает, что поиск будет проводиться по всей иерархии, а не только в элементах корневого уровня.

Теперь представим, что мы хотим сделать текущим элемент с заданной надписью:

Думаю, всё ясно: получаем список элементов, на которых написано dog (а такой элемент у нас один). Далее нам для элемента понадобился соответствующий ему объект QModelIndex. QModelIndex — это служебный класс для работы с положением элемента в иерархии. Поскольку у нас пример простой и мы заранее знаем, что искомый элемент у нас только один — значит, он находится в первом элементе списка, то есть доступен в list[0]. Вызываем с ним model->indexFromItem(), получаем модельный индекс. Что с ним делать дальше? У QTreeView есть особая модель для операций с выделением элементов. В QStandardItemModel нет таких функций, а вот у QItemSelectionModel они есть. И для обращения к указателю на экземпляр этой модели мы воспользовались функцией selectionModel():

tv->selectionModel()->setCurrentIndex (index, J QItemSelectionModel::Select);

Таким образом, мы вызвали функцию QItemSelectionModel:: setCurrentIndex(), чтобы сделать текущим элемент по модельному индексу index. И последний росчерк пера — вызов QTreeView:: scrollTo() для прокрутки видимой области к заданному индексу:

tv->scrollTo (index);

Класс QItemSelectionModel пригодится также, чтобы узнать индекс текущего элемента — он возвращается функцией currentIndex(). Получим текст выделенного элемента:

QModelIndex index = tv->selectionModel()->currentIndex();

QString item_ string = index.data().toString();

Для обращения к множеству выделенных элементов существуют функции selectedColumns (колонки по указанному ряду), selectedRows (индексы по колонке) и selectedIndexes (без критерия). Например, если модель представляет список файлов, то каждый ряд состоит из столбцов «имя файла», «размер», «дата», но вам нужно получить только выделенные имена (без размера и даты), то пишем примерно такой код:

QModelIndexList il = tree _ view->selectionModel()-> J QItemSelectionModel::selectedRows (0);

foreach (QModelIndex index, il)

{

qDebug() << index.data() .toString(); } Функция selectedRows() вернула нам в виде QModelIndexList список выделенных индексов из нулевой колонки — именно в ней имена файлов. Затем в цикле проходим по списку и выводим на консоль названия элементов. Не буду описывать сигналы, которые посылает QTreeView при выборе элемента, и тому подобное — для этого есть документация. Коснусь тонкостей работы с моделью и представлением. Перед любыми действиями с моделью, если она уже подключена к виджету отображения, модель лучше отключить от этого виджета. Вот так: tree _ view->setModel (0);

А обновив модель, потом снова подключить:

tree _ view->setModel (model);

Зачем? Каждое изменение модели приводит к отрисовке виджета отображения. Представьте теперь, что вы в цикле заполняете модель тысячью элементов. Виджет обновится тысячу раз. А при отключенной модели вы спокойно обновляете модель, затем подключаете ее к виджету, и тогда-то он рисует разом все элементы. После такого подключения обязательно снова переназначьте все сигналы, связанные с моделью selectionModel() виджета просмотра. Например:
connect (tree _ view->selectionModel(), SIGNAL(currentChanged J (const QModellndex &, const QModellndex &)), this, J SLOT(my _ currentChanged ( const QModellndex &, J const QModellndex &)));

Для управления шириной колонок используйте объект-заголовок, возвращаемый виджетом отображения через функцию header(). Например:

tree _ view->header()->setResizeMode J (QHeaderView: :ResizeToContents);

Функция header() у QTreeView возвращает указатель на используемый в виджете заголовок. Он является экземпляром класса QHeaderView. Изучите его подробно, потому что именно в нем заключены многие функции отображения не просто заголовка, но и содержимого модели вообще. Например, если вызвать функцию setStretchLastSection с параметром true, то последняя колонка в списке будет растянута до конца рабочей области виджета.

[:]
Новини [:ru]Програмирование[:]

Навигация по записям

Previous post
Next post

Related Posts

Новини WWDC 2025: Apple обновляет iOS, но искусственный интеллект в Siri завис в разработке

WWDC 2025: Apple обновляет iOS, но искусственный интеллект в Siri завис в разработке

08.06.2025

WWDC 2025 обещает стать знаковым событием для компании Apple, в частности благодаря ожидаемым обновлением iOS 26, новым функциям для iPad и гарнитуры Vision Pro. Однако все эти анонсы могут отойти на второй план из-за ключевой проблемы — провального запуска Siri со встроенным искусственным интеллектом.

Read More
Ігри та кіно NAVI зупинилися за крок до титулу BLAST Slam VI

NAVI зупинилися за крок до титулу BLAST Slam VI

19.02.202619.02.2026

Команда Natus Vincere стала віцечемпіоном BLAST Slam VI, поступившись у фіналі Team Liquid з рахунком 1:3.

Read More
Новини Ученые из Южной Кореи сумели совместить скорость оперативной памяти и энергонезависимость флэш-памяти в одной гибридной разработке

Ученые из Южной Кореи сумели совместить скорость оперативной памяти и энергонезависимость флэш-памяти в одной гибридной разработке

25.04.202428.06.2025

Ученым из Южной Кореи удалось совместить то, что до сих пор считалось несовместимым — скорость оперативной памяти с энергонезависимостью флэш-памяти.

Read More

Последние записи

  • Новий спосіб перемикання магнітної пам’яті зменшить енерговитрати ШІ
  • NAVI посіли четверте місце на Esports World Cup 2026
  • Кубок NAVI продемонструють фанатам у готелі Україна
  • Студія GSC та UNITED24 відкривають збір на розмінування ЧАЕС
  • S.T.A.L.K.E.R. 2 отримала перше сюжетне DLC

Последние коментарии

Нет комментариев для просмотра.

Категории

  • iT
  • Авто
  • Додатки
  • Ігри та кіно
  • Криптовалюта
  • Наука та космос
  • Новини
  • Пристрої
  • Статті
  • Штучний інтелект
©2026 wel.org.ua | WordPress Theme by SuperbThemes