Название: [РЕШЕНО] QTreeView с загрузкой данных при разворачи Отправлено: mugabe от Июнь 03, 2009, 09:49 Задача:
Есть огромная древовидная структура данных, загружаемая с удаленного сервера. Сразу грузить всю структуру - долго, да и не нужно. Нужно что бы сначала загружался первый уровень, а при разворачивании загружались только вложенные элементы. Пытался реализовать такое на базе примера Simple Tree Model (http://doc.trolltech.com/4.5/itemviews-simpletreemodel.html). Пока что ничего не вышло. Сначала пробовал загружать данные при первом обращении к TreeItem::data(...), child(...), childCount(...) и т.д. И в принципе даже работало, но возникала проблема во время отрисовке, когда вызывался один из вышеперечисленных методов, пока предыдущий вызов еще не успел завершить свою работу. Тут жабу подкинул класс-обертка для QHttp, позволяющая делать синхронные запросы - он вызывает QEventLoop::exec() до тех пор пока не получит ответ, что позволяет выполнить paintEvent() до того, как данные получены :( Это подтолкнуло поступить более правильно (на мой взгляд): 1. При разворачивании элемента он разворачивается, но показывает только один элемент с текстом "Загрузка...". При этом действия пользователя не блокируются и он может делать что-то еще, пока грузятся данные. 2. Когда данные будут загружены, этот элемент удаляется и добавляются настоящие элементы. Но с реализацией этого возникли трудоности. Возможно, из за недостаточного понимания Qt-шной модели MVC, в частности индексов. Сейчас у меня происходит следующее: 1. При первом вызове TreeItem::data(...), child(...), childCount(...) возвращается один элемент с надписью "Загрузка...". 2. В это время через обычный QHttp делается ассинхронный запрос к серверу. Сигнал QHttp::finished(...) привязывается к слоту моей модели requestFinished(...). 3. При завершении запроса срабатывает слот requestFinished(...), анализируются данные пришедшие от сервера и корректируются данные в необходимом TreeItem. И вот тут у меня загвоздка, как после этого дать понять TreeView, что модель обновилась? На сколько я понимаю нужно вызвать QAbstractItemModel::insertRow(int row, const QModelIndex &parent). Но как получить индекс QModelIndex &parent, если у меня есть только ссылка на TreeItem этого parent-а? Название: Re: QTreeView с загрузкой данных при разворачивании элемента Отправлено: EhTemka от Июнь 03, 2009, 14:49 TreeItem - это QTreeWidgetItem? Если да , то есть функция
Код
Название: Re: QTreeView с загрузкой данных при разворачивании элемента Отправлено: mugabe от Июнь 04, 2009, 04:16 TreeItem - это QTreeWidgetItem? Нет, это класс из Simple Tree Model (http://doc.trolltech.com/4.5/itemviews-simpletreemodel.html).Я работаю с QTreeView, а не QTreeWidget. Название: Re: QTreeView с загрузкой данных при разворачивании элемента Отправлено: drsm от Июнь 04, 2009, 05:33 я тупо храню QHash<RequestId, QModelIndex>,
а вызывать при вставке нужно не insertRow, а begin/endInsertRows(). Название: Re: QTreeView с загрузкой данных при разворачивании n Отправлено: mugabe от Июнь 04, 2009, 06:19 я тупо храню QHash<RequestId, QModelIndex>, а вызывать при вставке нужно не insertRow, а begin/endInsertRows(). Ну до вызова insertRow еще не дошло, т.к. индекс я не получил, так что пока не суть :) Я так понимаю, что QModelIndex можно хранить и в самом элементе, но если честно, плохо понимаю что происходит в QAbstractItemModel::index(...) Вот кусок из Simple Tree Model: Код
Что здесь нужно сделать, что бы хранить этот индекс в элементе? Код
комменты на русском как-то странно обрабатываются, на месте "comment here" хотел написать: // тут что-то вроде такого... сохраняем индекс в итеме и возвращаем его... // и может надо работать с указателями на индекс воизбежание копирования? Так правильно? Название: Re: QTreeView с загрузкой данных при разворачивании элемента Отправлено: Tonal от Июнь 04, 2009, 06:38 Посмотри в сторону canFetchMore и fetchMore.
Название: Re: QTreeView с загрузкой данных при разворачивании элемента Отправлено: mugabe от Июнь 04, 2009, 06:48 Смотрел - он не совсем подходит для такой задачи.
Да и проблемы у него те же. В общем попробовал сделать так, как предположил выше - работает! :) |