Russian Qt Forum

Qt => Model-View (MV) => Тема начата: KADABRA от Сентябрь 16, 2008, 01:32



Название: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: KADABRA от Сентябрь 16, 2008, 01:32
Пытаюсь реализовать отображение в QTreeView древовидной модели (класс наследуется от QAbstractItemModel) с подгрузкой вложенных элементов при раскрытии узла. Но QTreeView при раскрытии узла сначала отображает его, а уже потом вызывает fetchMore у модели - из за этого содержимое узла появляется только при втором открытии.
Не пойму такой логики - это в Qt бага или особенность какая?


Название: Re: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: ритт от Сентябрь 16, 2008, 05:11
давай упрощённый код твоей модели


Название: Re: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: KADABRA от Сентябрь 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) вызывается в самом конце.


Название: Re: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: Barmaglodd от Сентябрь 16, 2008, 11:43
А в fetchMore() сделать вставку нодов через beginInsertRows endInsertRows не пробовал?


Название: Re: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: ритт от Сентябрь 16, 2008, 14:13
ну, правльно. разворачивается нода - у тебя спрашивают - "сколько там строк?". ты отвечаешь - "0". хорошо, 0 - так 0. затем спрашивают - "а ещё есть?". ты - "да, есть - вот возьмите 50". "хорошо, возьму. только ты обнови меня". а ты - "ну уж нет. я тебе сказал 50 - само обновляйся"...


Название: Re: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: KADABRA от Сентябрь 16, 2008, 23:51
ну, правльно. разворачивается нода - у тебя спрашивают - "сколько там строк?". ты отвечаешь - "0". хорошо, 0 - так 0. затем спрашивают - "а ещё есть?". ты - "да, есть - вот возьмите 50". "хорошо, возьму. только ты обнови меня". а ты - "ну уж нет. я тебе сказал 50 - само обновляйся"...
Да, я такой  ;D

Спасибо, понял. Посылаю в fetchMore сигнал layoutChanged() - теперь обновляется как надо.
Но всё-таки, по моему, логчнее было бы если сначала вызывался fetchMore, а уже потом rowCount.


Название: Re: QAbstractItemModel::fetchMore, rowCount и QTreeView
Отправлено: ритт от Сентябрь 17, 2008, 00:17
советую посмотреть код инкрементальных моделей (например, QSqlQueryModel для случаев, когда драйвер не поддерживает QuerySize) - подобные "светлые" мысли сами собой пройдут...