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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QAbstractItemModel::fetchMore, rowCount и QTreeView  (Прочитано 8994 раз)
KADABRA
Гость
« : Сентябрь 16, 2008, 01:32 »

Пытаюсь реализовать отображение в QTreeView древовидной модели (класс наследуется от QAbstractItemModel) с подгрузкой вложенных элементов при раскрытии узла. Но QTreeView при раскрытии узла сначала отображает его, а уже потом вызывает fetchMore у модели - из за этого содержимое узла появляется только при втором открытии.
Не пойму такой логики - это в Qt бага или особенность какая?
Записан
ритт
Гость
« Ответ #1 : Сентябрь 16, 2008, 05:11 »

давай упрощённый код твоей модели
Записан
KADABRA
Гость
« Ответ #2 : Сентябрь 16, 2008, 10:39 »

Модель
Код
C
class Model :  public QAbstractItemModel {
Q_OBJECT
 
public:
Model(QSqlDatabase db, QObject *parent);
~Model();
 
int columnCount(const QModelIndex & parent = QModelIndex()) const;
int rowCount(const QModelIndex & parent = QModelIndex()) const;
bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const;
QModelIndex parent(const QModelIndex & index) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
 
void fetchMore(const QModelIndex & parent);
bool canFetchMore(const QModelIndex & parent) const;
 
private:
void setupModelData(DObject *parent);
 
QSqlDatabase itsDb;
DObject *itsRootItem;
}
 
 
Model::Model(QSqlDatabase db, QObject *parent)
: QAbstractItemModel(parent)
, itsDb(db)
{
itsRootItem = new DObject(0, QMap<QString, QVariant>());
setupModelData(itsRootItem);
}
 
int Model::columnCount(const QModelIndex & parent) const {
return 1;
}
 
int Model::rowCount(const QModelIndex & parent) const {
DObject *node;
if(!parent.isValid())
node = itsRootItem;
else
node = static_cast<DObject*>(parent.internalPointer());
return node->childCount();
}
 
bool Model::hasChildren(const QModelIndex & parent) const {
return true;
}
 
QModelIndex Model::parent(const QModelIndex & index) const {
// ...
}
 
Qt::ItemFlags Model::flags(const QModelIndex &index) const {
// ...
}
 
QVariant Model::data(const QModelIndex & index, int role) const {
// ...
}
 
QModelIndex Model::index(int row, int column, const QModelIndex & parent) const {
// ...
}
 
void Model::setupModelData(DObject *parent) {
// Тут загружаем чайлды из базы данных
parent->setLoaded(true);
}
 
void Model::fetchMore(const QModelIndex & parent) {
if(!parent.isValid())
return;
 
DObject *parentItem = static_cast<DObject*>(parent.internalPointer());
setupModelData(parentItem);
}
 
bool Model::canFetchMore(const QModelIndex & parent) const {
if(!parent.isValid())
return false;
 
DObject *parentItem = static_cast<DObject*>(parent.internalPointer());
return !parentItem->childsLoaded();
}
 
Класс DObject представляет ноду дерева - имеет ссылки на чайлдов, парента и хранит свои данные.

Вот при раскрытии узла Model::rowCount вызывается до Model::fetchMore - соответственно никаких чайлдов тогда в узле нету.
По коду QTreeViewPrivate::expand так оно и есть - model->fetchMore(index) вызывается в самом конце.
« Последнее редактирование: Сентябрь 16, 2008, 10:43 от KADABRA » Записан
Barmaglodd
Гость
« Ответ #3 : Сентябрь 16, 2008, 11:43 »

А в fetchMore() сделать вставку нодов через beginInsertRows endInsertRows не пробовал?
Записан
ритт
Гость
« Ответ #4 : Сентябрь 16, 2008, 14:13 »

ну, правльно. разворачивается нода - у тебя спрашивают - "сколько там строк?". ты отвечаешь - "0". хорошо, 0 - так 0. затем спрашивают - "а ещё есть?". ты - "да, есть - вот возьмите 50". "хорошо, возьму. только ты обнови меня". а ты - "ну уж нет. я тебе сказал 50 - само обновляйся"...
Записан
KADABRA
Гость
« Ответ #5 : Сентябрь 16, 2008, 23:51 »

ну, правльно. разворачивается нода - у тебя спрашивают - "сколько там строк?". ты отвечаешь - "0". хорошо, 0 - так 0. затем спрашивают - "а ещё есть?". ты - "да, есть - вот возьмите 50". "хорошо, возьму. только ты обнови меня". а ты - "ну уж нет. я тебе сказал 50 - само обновляйся"...
Да, я такой  Смеющийся

Спасибо, понял. Посылаю в fetchMore сигнал layoutChanged() - теперь обновляется как надо.
Но всё-таки, по моему, логчнее было бы если сначала вызывался fetchMore, а уже потом rowCount.
Записан
ритт
Гость
« Ответ #6 : Сентябрь 17, 2008, 00:17 »

советую посмотреть код инкрементальных моделей (например, QSqlQueryModel для случаев, когда драйвер не поддерживает QuerySize) - подобные "светлые" мысли сами собой пройдут...
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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