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

Новини a screenshot from the now-seized dark web leak site of the BlackSuit ransomware gang, which says German, European and U.S. authorities assisted in the takedown operation.

Владні органи конфіскували сервери банди-вимагачів BlackSuit

04.08.202512.08.2025

Німецькі прокурори повідомили, що спільна операція США та Європи призвела до конфіскації інфраструктури групи хакерів BlackSuit, відомої завдяки численним серйозним кібернападам останніх років. Цього тижня представники Німеччини заявили, що 24 липня було вилучено сервери та системи групи. Вони повідомили, що операція забезпечила «значні обсяги даних», які допоможуть у встановленні особи…

Read More
Новини Французька поліція затримала російського баскетболіста, звинуваченого у злочинах з програмами-вимагачами, згідно з повідомленням

Французька поліція затримала російського баскетболіста, звинуваченого у злочинах з програмами-вимагачами, згідно з повідомленням

03.08.2025

Влада Франції затримала російського професійного баскетболіста, якого підозрюють у причетності до банди, що займається програмами-вимагачами, згідно з інформацією агентства новин AFP. Данііл Касаткін грає за команду MBA Москва, яка є частиною VTB Об’єднаної ліги, що переважно складається з російських клубів, а також має одну команду з Білорусі та одну з…

Read More
Наука та космос Исследователи разработали технологию для получения электричества дронами из атмосферы

Исследователи разработали технологию для получения электричества дронами из атмосферы

29.05.202428.06.2025

Исследователи создали технологию, которая позволит беспилотным летательным аппаратам получать электроэнергию непосредственно из атмосферы.

Read More

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

  • У бета-версії iOS 27 Siri навчилася говорити швидше, повільніше та виразніше
  • Google випустила Gemini Spark для macOS
  • SpaceX працює над власним ШІ-пристроєм: чи так це насправді
  • Топ бюджетних смартфонів 2026: моделі, ціни, характеристики
  • Україна представить три дисципліни без кваліфікації на Esports Nations Cup 2026

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

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

Категории

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