Russian Qt Forum
Ноябрь 24, 2024, 09:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [Qt 4.x.x] Пара вопросов по Model/View  (Прочитано 15884 раз)
vregess
Гость
« : Январь 28, 2007, 19:46 »

Вот столкнулся с необходимостью использовать Model/View.
Начал изучать. Появились вопросы.

Вот, например, не ясно следующее поведение:
Дистрибутивный пример simpetreemodel, Класс treemodel метод data:
Код:

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    TreeItem *item = static_cast<TreeItem*>(index.internalPointer());

    return item->data(index.column());
}


Если убрать
Код:

if (role != Qt::DisplayRole)
        return QVariant();

то item'ы не отображаются. Не подскажите, почему так?

Немного не понятно, как использовать роли. Как их присваивать и потом использовать?

Создал свой delegate class для редактирования данных в ячейках и столкнулся с такой проблемой:
Допустим, в методе createEditor есть условие
Код:

if(что-то){
    создаем свой editor и возвращаем его
}
else
    return QItemDelegate::createEditor(parent, option, index);

Так вот при выполнении условия else, программа вылетает с Segmentation fault.
Где я ошибся?
Записан
alex12
Гость
« Ответ #1 : Январь 29, 2007, 12:49 »

Цитата: "vregess"


Если убрать
Код:

if (role != Qt::DisplayRole)
        return QVariant();

то item'ы не отображаются. Не подскажите, почему так?


return QVariant() -- это значение по умолчанию. Оно должно выдаваться для любых ролей, который не обрабатываются( Qt::FontRole, Qt::BackgroundRole ... и.т.д. ). Если убрать этот текст, то на все эти роли будут выдаваться некорректные ответы. Соответственно отображаться либо ничего не будет, либо будут всякие глюки.
Записан
vregess
Гость
« Ответ #2 : Январь 29, 2007, 19:00 »

Цитата: "alex12"

return QVariant() -- это значение по умолчанию. Оно должно выдаваться для любых ролей, который не обрабатываются( Qt::FontRole, Qt::BackgroundRole ... и.т.д. ). Если убрать этот текст, то на все эти роли будут выдаваться некорректные ответы. Соответственно отображаться либо ничего не будет, либо будут всякие глюки.


Понял. Спасибо большое.

Осталось выяснить по поводу ролей и делегатов...
Записан
vipet
Бывалый
*****
Offline Offline

Сообщений: 452


Просмотр профиля
« Ответ #3 : Февраль 02, 2007, 05:12 »

Цитировать
Немного не понятно, как использовать роли. Как их присваивать и потом использовать?


Их не надо присваивать.

Qt много раз вызывает метод data() модели, передавая аргументом разные роли (Qt::DisplayRole, Qt::TooltipRole и т.д.). А разработчик модели, в зависимости от переданного значения role, должен возвратить результат.

Например:
имеем класс с 3-мя данными-членами типа строка: Name, Group, Details.
- На запрос о Qt::DisplayRole модель, т.е. ее ф-ция data(), возвращает Group+": "+Name
(Если бы не model/view, то пришлось бы делать отдельную функцию типа DisplayName(), т.е. смешивать в одном классе данные и их представление)
- на запрос о Qt::ToolTipRole модель возвращает Details.
- Если (для элемента с текущим индексом) Group == "Group1" и роль==цвет фона, то вернуть черный цвет
и т.д. и т.п.


на вопрос о делегатах пока ответить не могу.
Записан
vregess
Гость
« Ответ #4 : Февраль 03, 2007, 19:12 »

Цитата: "vipet"

Qt много раз вызывает метод data() модели, передавая аргументом разные роли (Qt::DisplayRole, Qt::TooltipRole и т.д.). А разработчик модели, в зависимости от переданного значения role, должен возвратить результат.


Спасибо. Так, примерно, этот процесс и представлял.
Но зачем нужны UserRole? В смысле, как ими пользоваться?
Qt вызывает data() с UserRole? Или как?
Записан
vipet
Бывалый
*****
Offline Offline

Сообщений: 452


Просмотр профиля
« Ответ #5 : Февраль 04, 2007, 03:26 »

В слове UserRole часть "User" означает не пользователя твоей проги, а тебя, пользователя Qt Улыбающийся

Если ты написал свой View c каким-то специфическим поведением и тебе не хватает встроенных ролей, то тогда надо определить свои роли вот так:

myFirstRole = Qt::UserRole;
my2ndRole = Qt::UserRole + 1;
и т.д.

И в методе data() их анализировать.


Вот отрывок из хелпа, Basic Drawing Example:

Note that Qt::UserRole is only the first role that can be used for application-specific purposes. If you need to store different data in the same index, you can use different roles by simply incrementing the value of Qt::UserRole, for example: 'Qt::UserRole + 1' and 'Qt::UserRole + 2'. However, it is a good programming practice to give each role their own name: 'myFirstRole = Qt::UserRole + 1' and 'mySecondRole = Qt::UserRole + 2'. Even though we only need a single role in this particular example, we add the following line of code to the beginning of the window.cpp file.
 const int IdRole = Qt::UserRole;
Записан
vregess
Гость
« Ответ #6 : Февраль 04, 2007, 11:48 »

Цитата: "vipet"

В слове UserRole часть "User" означает не пользователя твоей проги, а тебя, пользователя Qt Улыбающийся

:shock: Я так сказал? Странно, что вы меня так поняли... Улыбающийся:shock:Улыбающийся Может я не правильно выразился... Улыбающийся
Понятно, что User означает "меня".

Цитата: "vipet"

И в методе data() их анализировать.

Получается, что data() вызывается как минимум на каждую qt-шную роль+на каждую UserRole.
Как Qt узнает, сколько, например, у меня своих ролей?
Сколько раз, интересно, вызывается data()? (засунуть printf?) )

добавлено спустя 13 минут:

 Вот, кстати, попутно вопрос возник.
Видом Item'a можно управлять как из метода модели data() [путем ролей], так и из метода делегата paint().
Какой способ лучше использовать?
Записан
nova
Гость
« Ответ #7 : Февраль 04, 2007, 11:53 »

Если прикрутить твою модель к стандартному представлению, дата с UserRole не вызовется ни разу, так как для работы представления эти данные не нужны.
Если прикрутить к стандартной модели твое представление, дата с UserRole будет вызыватся столько раз, сколько необходимо для работы ТВОЕГО представления, а в ответ всегда получиш QVariant(), так как в модели нет запрашиваемых данных.
В принципе колличество UserRole в модели и представлении могут не совпадать, и на одну модель можно повесить много представлений, каждомк из которых нужны разные UserRole Улыбающийся
Записан
vipet
Бывалый
*****
Offline Offline

Сообщений: 452


Просмотр профиля
« Ответ #8 : Февраль 04, 2007, 12:20 »

vregess,
Цитировать
Я так сказал? Странно, что вы меня так поняли... Может я не правильно выразился... Smile Понятно, что User означает "меня".


Нет, я лишь предположил, что можно было так подумать. И предлагаю перейти на ты Улыбающийся я все равно уже так начал Подмигивающий

Цитировать
Видом Item'a можно управлять как из метода модели data() [путем ролей], так и из метода делегата paint().
Какой способ лучше использовать?


Ну если пишешь свою модель, а делегат стандартный, то из data()
Записан
Alexei
Гость
« Ответ #9 : Февраль 04, 2007, 14:09 »

Насчет делегата. Так как ты написал должно работать. На всякий случай напиши здесь свою реализацию
::createEditor(QWidget* parent, const QStyleOptionViewItem& option,  const QModelIndex& index) const
Записан
vregess
Гость
« Ответ #10 : Февраль 04, 2007, 15:19 »

Цитата: "nova"
Если прикрутить твою модель к стандартному представлению, дата с UserRole не вызовется ни разу, так как для работы представления эти данные не нужны.
Если прикрутить к стандартной модели твое представление, дата с UserRole будет вызыватся столько раз, сколько необходимо для работы ТВОЕГО представления, а в ответ всегда получиш QVariant(), так как в модели нет запрашиваемых данных.
В принципе колличество UserRole в модели и представлении могут не совпадать, и на одну модель можно повесить много представлений, каждомк из которых нужны разные UserRole Улыбающийся

ААА! До меня дошло! наверное...
UserRole нужны для своих представлений...
Спасибо. Это проясняет ситуацию....

добавлено спустя 13 минут:

 
Цитата: "Alexei"
Насчет делегата. Так как ты написал должно работать. На всякий случай напиши здесь свою реализацию
::createEditor(QWidget* parent, const QStyleOptionViewItem& option,  const QModelIndex& index) const


Привожу свою реализации. Да, скажу еще, чего хочу добиться: просто пытаюсь сделать свой property editor. Вот и разбираюсь с model/view. Не хотел смотреть чужой код, т.к. рано туда (было) заглядывать. Скоро полезу и туда. Но это все лирика...
Код:

QWidget* DelegateEditor::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QString type=static_cast<DataItem*>(index.internalPointer())->data(2).toString();
if(type=="char" || type=="int"){
QList<QVariantMap> Values=static_cast<DataItem*>(index.internalPointer())->getValues();
QSpinBox *editor=new QSpinBox(parent);
editor->setMinimum(0);
editor->setMaximum(100);
editor->installEventFilter(const_cast<DelegateEditor*>(this));
return editor;
} else{
return QItemDelegate::createEditor(parent, option, index);
}
}

этот код вызывает у меня segFault и под виндами и под линуксом.
Делал по примеру. Qt 4.1.4 OpenSource mingw.
Записан
nova
Гость
« Ответ #11 : Февраль 04, 2007, 16:10 »

ошибку вызывает строка:
Код:

QString type=static_cast<DataItem*>(index.internalPointer())->data(2).toString();

Сделай проверку:
Код:

index.isValid()

с соответствующими выводами Улыбающийся

И вообще, ни кто не находил внятного примера с полным переопределением методов QItemDelegate? Поделеитесь ссылочкой!
Записан
vregess
Гость
« Ответ #12 : Февраль 05, 2007, 20:48 »

Цитата: "nova"
ошибку вызывает строка:
Код:

QString type=static_cast<DataItem*>(index.internalPointer())->data(2).toString();

Сделай проверку:
Код:

index.isValid()

с соответствующими выводами Улыбающийся

Хм...
Код:

QWidget* DelegateEditor::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return QItemDelegate::createEditor(parent, option, index);
}

Вылетает... Видимо проблема не в этом. Но все равно спасибо, т.к. на эту ошибку я все равно натолкнулся бы )

Цитата: "nova"

И вообще, ни кто не находил внятного примера с полным переопределением методов QItemDelegate? Поделеитесь ссылочкой!


Я смотрел на код примера в книге "C++ GUI Programming with Qt 4
  By Jasmin Blanchette, Mark Summerfield".
Chapter 10 -> Implementing Custom Delegates.
Это не внятный пример?
Могу выслать код, если нет книги под рукой. Хотя валяется она где-то не далеко Улыбающийся...
Записан
vipet
Бывалый
*****
Offline Offline

Сообщений: 452


Просмотр профиля
« Ответ #13 : Февраль 05, 2007, 21:41 »

Здесь есть неплохая дока по делегатам:

http://www.ics.com/developers/papers/

Qt 4's Model/View Delegates
Записан
nova
Гость
« Ответ #14 : Февраль 05, 2007, 23:24 »

А ни кто не встречал "C++ GUI Programming with Qt 4  By Jasmin Blanchette, Mark Summerfield" в пдф, а то схм читать нечем Грустный :cry: :cry:

Цитировать

Здесь есть неплохая дока по делегатам:
 
 http://www.ics.com/developers/papers/
 
 Qt 4's Model/View Delegates

То что надо !!! Улыбающийся Улыбающийся Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.058 секунд. Запросов: 23.