Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QVariant data() роли.
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
Ponchikus
Здравствуйте!!!

Начал потихоньку изучать модель/представление.

Появилось пару вопросов, прошу разъяснить мне простым языком некоторые моменты.
А именно.

Первое. Как вообще использовать роли ? Как они вызываются в приложении, для чего они вообще нужны и что с ними можно делать??

Второе. Функция QVariant data(const QModelIndex &index, int role) const; Когда она вызывается? Кто ее вызывает? Сама роль вызывает эту функцию?

Третье. В документации, есть описание -
Описание
Роли элемента
Роль указывает модели, данные какого типа будут переданы. Представления могут отображать роли различными способами, поэтому важно обеспечить информацию, соответствующую каждой роли.

Не могли бы вы пояснить ее более простыми словами, с примерами, если можно.

Помогите понять, что-то вообще не могу сообразить как все устроено...

СПАСИБО!
lanz
1. Стандартные роли используются стандартными видами в Qt
Здесь описано для чего нужна каждая
http://doc.qt.io/qt-4.8/qt.html#ItemDataRole-enum
Минимально необходимая это Qt::DisplayRole

Роли не вызываются, это просто числа. Представьте что скаждым элементом модели у вас ассоциировано некоторое количество данных:
- текст который показывается пользователю
- картинка
- подсказка
Когда мы говорим модели дай нам данные для элемента Х, мы указываем для чего именно нам нужны данные
Qt::DisplayRole - текст, покажем пользователю, модель должна вернуть текст
Qt::DecorationRole - картинку нарисуем, модель должна вернуть картинку
Qt::ToolTipRole - подсказку по данному элементу

2. Функцию data может вызвать кто угодно, обычно ее вызывает вид(представление)
Эта функция как раз для того чтобы получить данные которые содержит модель.

3. Обязательных ролей нет, но если не обеспечить хотя бы Qt::DisplayRole или Qt::DecorationRole, то ничего не отобразится.

Вот хорошее описание
http://doc.qt.io/qt-4.8/modelview.html
Ponchikus
Спасибо за ответ!

1. Т.е. если я правильно понял. К примеру создаем QList<int> list, и записываем туда элементы данных - list<<15<<29<<5;
То вот у каждого элемента (15 , 29 , 5 ), например у 29 - есть набор (лично этого элемента данных) ролей(констант), и именно от этого элемента представление вызывает роли?

К примеру навели мышкой на элемент данных 29, и представление вызывает функцию data() с ролью подсказки (Qt :: ToolTipRole) т.е. передает в функцию индекс модели и константу 13.

Правильно ???

И вот по третьему пункту не совсем понятно вот это -- "Роль указывает модели, данные какого типа будут переданы." Какие данные ??

СПАСИБО!
lanz
Цитата
К примеру навели мышкой на элемент данных 29, и представление вызывает функцию data() с ролью подсказки (Qt :: ToolTipRole) т.е. передает в функцию индекс модели и константу 13.

Это верно.

Цитата
и именно от этого элемента представление вызывает роли?

Нужно прояснить, что значит "вызывает роли", пока я не понял :lol:

Цитата
И вот по третьему пункту не совсем понятно вот это -- "Роль указывает модели, данные какого типа будут переданы." Какие данные ??

QVariant, который вернется из функции data.
Ponchikus
Цитата
Нужно прояснить, что значит "вызывает роли", пока я не понял :lol:


Проясняю :lol: . "Вызывает роли". Имеется ввиду, что, у элемента данных, т.е. 29, имеется набор ролей, в смысле у каждого элемента данных, есть его собственный набор ролей(Qt::DisplayRole, Qt::ToolTipRole, и т.д.) У 29, свой Qt::DisplayRole, у 15 свой Qt::DisplayRole. И вот когда я навожу мышку на элемент 29, то он передает в функцию data() именно свою роль Qt::ToolTipRole. А 15 будет передавать свою роль Qt::DisplayRole.

Я правильно понимаю? Это так ??


Цитата
QVariant, который вернется из функции data.


Все равно не могу понять... :(
Получается если в модели лежат данные типа int (29, 15, 5), то QVariant вернет int ?
lanz
Цитата
Я правильно понимаю? Это так ??

Есть две точки зрения
1. С точки зрения представления - внешний интерфейс модели:
У нас есть модель, неважно где мы ее взяли:
QAbstractItemModel * mdl;

в которой три строки
mdl->rowCount(); // возвращает 3

в которой есть один столбец
mdl->columnCount(); // возвращает 1

получим индекс первой строки первого столбца
QModelIndex idx = mdl->index(0, 0); //нумерация с 0

получим данные для этого элемента
idx.data( Qt::DisplayRole ) или mdl->data( idx, Qt::DisplayRole ); //возвращает QVariant который можно преобразовать в строку "29" (или в число 29, обычно это неважно)
idx.data( Qt::ToolTipRole ) или mdl->data( idx, Qt::ToolTipRole ); //возвращает QVariant который можно преобразовать в строку "Это число!" (например)
idx.data( Qt::DecorationRole ) или mdl->data( idx, Qt::DecorationRole ); //возвращает невалидный QVariant :(

теперь напишем в нужной ячейке текст, который мы получили ("29")
если пользователь навел мышку в ячейку, покажем подсказку ("Это число!")
не будем рисовать иконку, модель ничего не вернула :(

2. Та же самая модель, вид изнутри
class MyModel : public QAbstractListModel {
// .. конструктор
// .. объявления методов
  QVector<int> list = { 29, 15, 5 };
}

int MyModel::rowCount( .. ) {
  return list.size();
}

int MyModel:: columnCount( .. ) {
  return 1;
}

QVariant MyModel::data( const QModelIndex & idx, Qt::ItemDataRole role ) {
  if( role == Qt::DisplayRole ) return list[ idx.row() ];
  if( role == Qt::ToolTipRole ) return "Это число!"; // Для всех элементов подсказка одинаковая

  return QVariant(); // Больше никаких данных ассоциированных с этим элементом (и нет картинки :( )
}
Ponchikus
Кажется понимаю. QVariant вернет тип данных, в зависимости от роли, которую передаем в метод data().
Таким образом, если мы сделаем вот так:

QVariant MyModel::data( const QModelIndex & idx, Qt::ItemDataRole role ) {
  if( role == Qt::SizeHintRole) return QSize(10,10);


QVariant преобразуется в QSize, и изменит размер ячейки (10,10)??

А как тогда модель определяет, какая именно роль в данный момент ей передается?? Это похоже на обработчика событий (QPaintEvent, QResizeEvent...)??
lanz
Цитата
QVariant преобразуется в QSize, и изменит размер ячейки (10,10)??

Ну это зависит от реализации конкретного представления, может поменять, а может проигнорировать :lol:

Цитата
А как тогда модель определяет, какая именно роль в данный момент ей передается?? Это похоже на обработчика событий (QPaintEvent, QResizeEvent...)??

Да вот же она, передается как параметр:
QVariant MyModel::data( const QModelIndex & idx, Qt::ItemDataRole role )
Ponchikus
Цитата
А как тогда модель определяет, какая именно роль в данный момент ей передается?? Это похоже на обработчика событий (QPaintEvent, QResizeEvent...)??

Цитата
Да вот же она, передается как параметр:
QVariant MyModel::data( const QModelIndex & idx, Qt::ItemDataRole role )



Это понятно, а как представление определяет с какой именно ролью вызывать эту функцию?? Т.е. как представление определяет что сейчас передается роль Qt::ToolTipRole, откуда оно узнаёт что мы передаётся роль 13(Qt::ToolTipRole) ?
lanz
Цитата
Это понятно, а как представление определяет с какой именно ролью вызывать эту функцию?? Т.е. как представление определяет что сейчас передается роль Qt::ToolTipRole, откуда оно узнаёт что мы передаётся роль 13(Qt::ToolTipRole) ?

Нужно ей тултип показать - она передает ToolTipRole,
Нужно ячейку перерисовать, передает DisplayRole,
В общем по мере надобности :lol: А уж представление знает когда что ему нужно.

А то какая роль за что отвечает - это соглашение.
Ponchikus
Вроде все понятно стало. Спасибо Вам большое, lanz, за объяснение и терпение!!! :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2021 IPS, Inc.