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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с деревом QTreeView. Из QModelIndex получить TreeItem легко. А наоборот?  (Прочитано 15072 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« : Январь 22, 2009, 00:50 »

Здравствуйте!


Вот пишу я, пишу прогу. В основе лежит пример /examples/itemviews/editabletreemodel. И такой уродливый код приходится писать... А все потому, что при работе с древовидными данными мне часто требуется две вещи:

1. Получить по известному QModelIndex указатель на TreeItem
2. Получить по известному указателю на TreeItem значение QModelIndex

Первая вещь реализуется легко - преобразование можно сделать через метод модели getItem()

Код:
TreeItem *TreeModel::getItem(const QModelIndex &index) const
{
    if (index.isValid()) {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        if (item) return item;
    }
    return rootItem;
}

А вот как сделать вторую вещь, я теряюсь в догадках. Есть мысля хранить QModelIndex в каждом TreeItem элементе. Но это неправильно, ибо QModelIndex динамически меняется, и в доке сказано, что хранить эти данные бессмысленно. Кроме того, усложняется инициализация нового TreeItem элемента, да и вообще, инициализация дерева модели начинает зависеть от вида, что не есть правильно.

Есть еще мысля делать поиск по виду, получая из QModelIndex каждой ветки TreeItem, и сравнивая его с искомым указателем. Это более реально, проблема только в получении внутри модели значения QModelIndex для корневого элемента вида. Но это значение можно передавать извне как параметр, ибо извне, зная ссылку на вид, получить QModelIndex первого элемента вида легко. Недостаток - поиск зависит от размера дерева, что при большом дереве приведет к достаточно медленному процессу получения QModelIndex из TreeItem.

Вопрос - как сделать наиболее правильно? А может быть, эта задача решается в две строчки, а я не знаю как?
Записан

Собираю информацию по крупицам
http://webhamster.ru
Dendy
Гость
« Ответ #1 : Январь 22, 2009, 01:35 »

Хочется узнать, в каком именно случае вам потребовалось такое преобразование?
Записан
vaprele07
Гость
« Ответ #2 : Январь 22, 2009, 04:21 »

createIndex!
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #3 : Январь 22, 2009, 08:26 »

Хочется узнать, в каком именно случае вам потребовалось такое преобразование?

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

Дерево хранится в XML. При старте программы оно раскладывается по элементам TreeItem. Элементы TreeItem, помимо названия веток дерева, ссылок на родителя и списка ссылок на потомков, хранят и другие данные. В частности, id ветки (хранится в XML, уникальный для каждой ветки).

При закрытии программы, в конфиг сохраняется строка пути до рабочей ветки в виде перечисленных id. При старте программы, эта строка считывается. В терминах TreeItem легко находится нужный TreeItem (т.к. в TreeItem хранится id). После этого, надо курсор поставить на ветку, соответсвующую нужному TreeItem. Вот тут и требуется преобразование TreeItem в QModelIndex.

Еще удобно такое преоразование делать при операциях вставки/удаления элементов дерева, когда в конце процедуры нужно установить курсор на нужный TreeItem. Обычно, при вставке/удалении веток, TreeItem и его соседи известны. А для того чтобы в конце установить курсор куда нужно, приходится синхронно делать действия с TreeItem и QModelIndex.
Записан

Собираю информацию по крупицам
http://webhamster.ru
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #4 : Январь 22, 2009, 08:56 »

createIndex!

Не догоняю я, как этим createIndex() пользоваться. Пробую так

Код:
QModelIndex knowtreemodel::get_item_index(TreeItem *item)
{
 int itemrow=item->childNumber();
 
 return QAbstractItemModel::createIndex(itemrow,0,item->parent());
}

И так

Код:
 return this->createIndex(itemrow,0,item->parent());

получаю сегфолт при попытке воспользоваться (установить курсор) на сгенерированный QModelIndex.
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #5 : Январь 22, 2009, 09:04 »

QAbstractItemModel::createIndex ?Улыбающийся
а который из них используется для QAbstractItemModel::createIndex(itemrow,0,item->parent()); ?
« Последнее редактирование: Январь 22, 2009, 09:08 от Константин » Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #6 : Январь 22, 2009, 09:55 »

QAbstractItemModel::createIndex ?Улыбающийся
а который из них используется для QAbstractItemModel::createIndex(itemrow,0,item->parent()); ?

Не понял вопроса. knowtreemodel - естественно, унаследован от QAbstractItemModel. Посему return this->createIndex(itemrow,0,item->parent()); как бе должно работать, но не работает. В доке описание краткое, понять как пользоваца createIndex() сложно.

Кароче, сделал через поиск. Может быть и медленно, зато работает. Причем, "проблема только в получении внутри модели значения QModelIndex для корневого элемента. Но это значение можно передавать извне" - это я уже ступил... ничего извне передавать не надо.

Код http://paste.org.ru/?cagbcf (75 строк).
Записан

Собираю информацию по крупицам
http://webhamster.ru
vaprele07
Гость
« Ответ #7 : Январь 22, 2009, 10:06 »

не item->parent() а... createIndex(itemrow, 0, item);
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #8 : Январь 22, 2009, 11:23 »

не item->parent() а... createIndex(itemrow, 0, item);

Во, спасиба, так заработало, зря перебор дерева писал.
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #9 : Январь 22, 2009, 12:04 »

> Не понял вопроса...
я к тому, что там штуки четыре этих createIndex, и, не зная что отдаёт item->parent(), можно лишь догадываться какой из них используется и в чём причина сегфолта...вапреле угадал Улыбающийся
Записан
Setner
Гость
« Ответ #10 : Январь 26, 2013, 09:24 »

Вопрос снят
« Последнее редактирование: Январь 26, 2013, 14:31 от Setner » Записан
Bepec
Гость
« Ответ #11 : Январь 26, 2013, 09:30 »

Потому что на каждый новый вопрос нужно создавать новую тему. А так же описать что вы вообще хотите сделать )

PS ваш КО.
Записан
Setner
Гость
« Ответ #12 : Январь 26, 2013, 09:34 »

Ладно, буду знать на будущее.
Если можно, удалите последние сообщения здесь.
« Последнее редактирование: Январь 26, 2013, 09:38 от Setner » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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