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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Иерархическая модель  (Прочитано 20815 раз)
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #15 : Апрель 07, 2016, 15:08 »

ну добавь в Product поле типа Delivery *
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
KlimichKartorgnusov
Гость
« Ответ #16 : Апрель 07, 2016, 15:45 »

Там же ссылка на простой пример

Для одних это может и простой пример, а для других не очень Улыбающийся.

Мне для задания нужно разобраться c QAbstract(Table/List/Item)Model. С первыми двумя разобрался в легкую, а как организовать дерево, я не понимаю. Не понимаю как будет работать data(), rowCount() и прочие обязательные для переопределения функции.

Если сразу не понятно, то на пальцах тоже может не получится просто объяснить. Тут могут помочь в решении, но в "пустоту" трудно код писать. Рекомендую сделать простой проект, аналогично пример, с вашими структурами данных, и всеми необходимыми методами, которые надо переопределить. Чтобы можно было его взять и туда код вписать. И помогающим будет проще, и помогаемым понятней Улыбающийся.

Добавил код, ток что то не верится что за меня кто то будет делать. У меня такого никогда не прокатывало  Улыбающийся
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #17 : Апрель 07, 2016, 16:35 »

Как один из возможных вариантов...

Со структурой такого типа как QList<Delivery> deliveries_ получается всего два уровня в "дереве". Сама структура Delivery не "деревянная", значит QModelIndex::internalPointer() задействовать именно как указатель особо не получится, но оно не сильно и нужно. Вместо этого необходимо где-то хранить уровень дерева, можно в том же QModelIndex::internalPointer(), как int 1,2 (а лучше enum завести).

Навскидку:
Код
C++ (Qt)
QModelIndex DiliveriesModel::index(int row, int column, const QModelIndex &parent) const
{
   if (!hasIndex(row, column, parent))
       return QModelIndex();
 
   int tree_level;
 
   if (!parent.isValid()) // ???
       tree_level = 1;
   else
       tree_level = 2;
 
   if (/* check row and column */)
       return createIndex(row, column, tree_level);
   else
       return QModelIndex();
}
 

В остальных методах действовать аналогично. Где в примере использовалось
Код
C++ (Qt)
parentItem = static_cast<TreeItem*>(parent.internalPointer());
приводить к уровню дерева
Код
C++ (Qt)
tree_level = static_cast<int>(parent.internalPointer());

В
Код
C++ (Qt)
QVariant DiliveriesModel::data(const QModelIndex &index, int role) const
{
}
опять же из индекса QModelIndex &index и его internalPointer() получать уровень дерева и работать соответственно с Delivery или Product. Если internalPointer() слишком кривое место для хранения уровня дерева, то найти получше Улыбающийся.
Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #18 : Апрель 07, 2016, 16:46 »

Хотя для второго уровня надо ещё родительский индекс правильно определять, чтобы знать из какого Delivery брать Product. Либо с указателями работать, либо ещё как-то извращаться.

В общем-то если уровней всего два, то если internalPointer() == NULL, то находимся в корне, работать с QList<Delivery> deliveries_, если internalPointer() == -1, то это лист с Product, иначе указатель на соответствующий Delivery. Куда-то в этом направлении копать Улыбающийся.

Можно ещё в этом  internalPointer() хранить индекс Delivery в списке QList<Delivery>. Если -1, значит в корне.
« Последнее редактирование: Апрель 07, 2016, 16:59 от ViTech » Записан

Пока сам не сделаешь...
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #19 : Апрель 07, 2016, 16:50 »

ну добавь в Product поле типа Delivery *
+1
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #20 : Апрель 07, 2016, 16:56 »

ну добавь в Product поле типа Delivery *
+1

Не должны всякие деревянные модели на исходные структуры данных влиять. Это модель должна под исходные данные подстраиваться, а не наоборот.
Записан

Пока сам не сделаешь...
KlimichKartorgnusov
Гость
« Ответ #21 : Апрель 07, 2016, 17:06 »

Хотя для второго уровня надо ещё родительский индекс правильно определять, чтобы знать из какого Delivery брать Product. Либо с указателями работать, либо ещё как-то извращаться.

В общем-то если уровней всего два, то если internalPointer() == NULL, то находимся в корне, работать с QList<Delivery> deliveries_, если internalPointer() == -1, то это лист с Product, иначе указатель на соответствующий Delivery. Куда-то в этом направлении копать Улыбающийся.

Можно ещё в этом  internalPointer() хранить индекс Delivery в списке QList<Delivery>. Если -1, значит в корне.

Это все интересно и выглядит логично, но я все равно не въезжаю как представление строит модель. Представление дергает функцию data(). Как? Рекурсивно? Как она догадывается от структуре исходных данных. Простите пожалуйста меня за мою тупость, просто хочется все разъяснить для себя.

Поправка. rowCount() и columnCount() за это отвечают ?
« Последнее редактирование: Апрель 07, 2016, 17:20 от KlimichKartorgnusov » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #22 : Апрель 07, 2016, 17:21 »

rowCount сообщает, есть ли потомки.
если я вас правильно понял
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Апрель 07, 2016, 17:27 »

ну добавь в Product поле типа Delivery *
и Product стал неперемещаемым...

Это все интересно и выглядит логично, но я все равно не въезжаю как представление строит модель. Представление дергает функцию data(). Как? Рекурсивно? Как она догадывается от структуре исходных данных.
Корневые эл-ты - просто по индексу строки. Чилдренов - от корневого (rowCount(QModelIndex)). И представление не строит - всего лишь опирается на методы модели.

Ни разу еще не писал свою модель - не было приличных данных. А тогда проще не подстраивать "оригинал" под модель, а просто копировать его в удобный QTreeWidget  Улыбающийся
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #24 : Апрель 07, 2016, 17:28 »

Это все интересно и выглядит логично, но я все равно не въезжаю как представление строит модель. Представление дергает функцию data(). Как? Рекурсивно? Как она догадывается от структуре исходных данных. Простите пожалуйста меня за мою тупость, просто хочется все разъяснить для себя.

Давно я с этим возился, уже позабывал всё Улыбающийся. Чтоб не врать и вводить в заблуждение, лучше посоветую собрать приложение хотя бы из того же примера, поставить точки останова в методы и посмотреть, когда, что и в каком порядке вызывается.

А так в общем да, представление вызывает метод data() модели, когда надо что-то отобразить в ячейке с заданным индексом. Так же вызывает и другие методы, когда определяет свои размеры row column и прочее. Само представление к исходным данным не обращается, ему нужны QVariant, которые предоставляет метод data() модели. Структура исходных данных формируется в виртуальных методах QAbstractItemModel, особо важные из них чистые виртуальные, поэтому их и надо переопределять, чтобы дать минимальное представление о модели. Подробности в документации Улыбающийся.
Записан

Пока сам не сделаешь...
KlimichKartorgnusov
Гость
« Ответ #25 : Апрель 07, 2016, 17:35 »

Это все интересно и выглядит логично, но я все равно не въезжаю как представление строит модель. Представление дергает функцию data(). Как? Рекурсивно? Как она догадывается от структуре исходных данных. Простите пожалуйста меня за мою тупость, просто хочется все разъяснить для себя.

Давно я с этим возился, уже позабывал всё Улыбающийся. Чтоб не врать и вводить в заблуждение, лучше посоветую собрать приложение хотя бы из того же примера, поставить точки останова в методы и посмотреть, когда, что и в каком порядке вызывается.

А так в общем да, представление вызывает метод data() модели, когда надо что-то отобразить в ячейке с заданным индексом. Так же вызывает и другие методы, когда определяет свои размеры row column и прочее. Само представление к исходным данным не обращается, ему нужны QVariant, которые предоставляет метод data() модели. Структура исходных данных формируется в виртуальных методах QAbstractItemModel, особо важные из них чистые виртуальные, поэтому их и надо переопределять, чтобы дать минимальное представление о модели. Подробности в документации Улыбающийся.

Большое вам спасибо. Вы дали хороший пинок в сторону решения моей проблемы.
Записан
KlimichKartorgnusov
Гость
« Ответ #26 : Апрель 07, 2016, 17:38 »

ну добавь в Product поле типа Delivery *
и Product стал неперемещаемым...

Это все интересно и выглядит логично, но я все равно не въезжаю как представление строит модель. Представление дергает функцию data(). Как? Рекурсивно? Как она догадывается от структуре исходных данных.
Корневые эл-ты - просто по индексу строки. Чилдренов - от корневого (rowCount(QModelIndex)). И представление не строит - всего лишь опирается на методы модели.

Ни разу еще не писал свою модель - не было приличных данных. А тогда проще не подстраивать "оригинал" под модель, а просто копировать его в удобный QTreeWidget  Улыбающийся

Хоть перетаскивания и не будет у модели, вполне логично иметь обратную связь Product с его Delivery. Спасибо.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #27 : Апрель 07, 2016, 17:41 »

Рекомендую особое внимание уделить методам parent и index. У меня при изучении была проблема с ними. Скорее всего, вам просто достаточно будет передрать их из примера с небольшими корректировками.
Записан
Jaxx
Гость
« Ответ #28 : Апрель 08, 2016, 10:01 »

У меня была похожая проблема. http://www.prog.org.ru/topic_30005_0.html
Может поможет.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #29 : Апрель 08, 2016, 10:32 »

У научного работника мелькнула здравая мысль
Не должны всякие деревянные модели на исходные структуры данных влиять. Это модель должна под исходные данные подстраиваться, а не наоборот.
Которая впрочем сразу растворилась в хоре "передрать". Ну а действительно, вот исходные данные
Код:
class Delivery
{
public:
...

private:
int deliveryNumber_;
QDate deliveryDate_;
QList<Product> deliveredProducts_;
}
Была простая (или простейшая) организация данных, но оказывается на нее надо навесить виртуалы, добавить указатели на родителя и.т.п. - боже, во что это превратилось? Не хватает только бодрых фраз типа "Вьюха только отобоажает" - "а модель хранит". Мол, отображение не зависит от данных, они первичны. Но ведь только что мы искалечили исходные данные до неузнаваемости только потому что .. "иначе табличка не будет работать", т.е. в угоду UI.  Где же "независимость"?

Так ли уж хорошо делать исходные данные моделью, нет ли других подходов?
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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