Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: xintrea от Октябрь 27, 2010, 14:46



Название: [Решено] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 14:46
Здравствуйте!


Что-то я как-то неправильно код начал писать, теперь не знаю как разрулить.

У меня есть виджет, на котором лежит дерево QTreeView. К этому дереву подключена модель knowTreeModel (наследник класса QAbstractItemModel).

Мне нужно реализовать добавление подветки (из специального компактного представления) к указанному через QModelIndex элементу. Подветка добавляется последней в список пожветок элемента. Нужно чтобы после добавления добавленная ветка стала видна.

Я использую такой код. На входе переменная TreeItem *item указывает на элемент, к которому надо добавить подветку:

Код
C++ (Qt)
// Определяется количество подветок у элемента
int item_rows=item->childCount();
qDebug() << "paste_branch_smart() : Subbranch count " << item_rows;
 
// Определяется QModelIndex из TreeItem
QModelIndex item_index=knowTreeModel->get_index_by_item(item);
 
// Проверка, правильно ли определен QModelIndex из TreeItem
int n=knowTreeModel->getItem(item_index)->childCount();
qDebug() << "paste_branch_smart() : Subbranch count for item by index" << n;
 
// Модель оповещается что будет добавление подветки
knowTreeModel->beginInsertRows_middle(item_index, item_rows, item_rows);
 
 
// Добавляется подветка в Item-представление
knowTreeModel->paste_subbranch(item, (clipbbranch *)branch);
 
 
// Модель оповещается, что добавление окончено
knowTreeModel->endInsertRows_middle();
 
// Вид обновляется
knowTree->update();

Код для beginInsertRows_middle() / ndInsertRows_middle() следующий:

Код
C++ (Qt)
void KnowTreeModel::beginInsertRows_middle( const QModelIndex & parent, int first, int last )
{
beginInsertRows(parent, first, last);
}
 
 
void KnowTreeModel::endInsertRows_middle()
{
endInsertRows();
}

Отладочный вывод показывает, что используется правильный QModelIndex:

Цитировать
paste_branch_smart() : Subbranch count 17
paste_branch_smart() : Subbranch count for item by index 17

Однако после выполнения этого кода, в Item-представлении новые данные добавляются, а на экране новая подветка не появляется.

Вопрос. Почему так? Что нужно сделать, чтобы увидеть строку с новой подветкой?


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: nitro2005 от Октябрь 27, 2010, 14:57
Проверьте knowTreeModel->rowCount(item_index) до beginInsertRows и после endInsertRows.
Кроме того, какой номер колонки: item_index.column() - должен быть нуль.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 15:14
Проверьте knowTreeModel->rowCount(item_index) до beginInsertRows и после endInsertRows.
Кроме того, какой номер колонки: item_index.column() - должен быть нуль.

Добавил еще такой код:

Код
C++ (Qt)
qDebug() << "paste_branch_smart() : Row count for index, before" << knowTreeModel->rowCount(item_index);
qDebug() << "paste_branch_smart() : Column, before" << item_index.column();
 
...
 
qDebug() << "paste_branch_smart() : Row count for index, after" << knowTreeModel->rowCount(item_index);
qDebug() << "paste_branch_smart() : Column, after" << item_index.column();

В результате получаю:

Цитировать
paste_branch_smart() : Subbranch count  17
paste_branch_smart() : Subbranch count for item by index 17
paste_branch_smart() : Row count for index, before 17
paste_branch_smart() : Column, before 0
...
paste_branch_smart() : Row count for index, after 18
paste_branch_smart() : Column, after 0

То есть, ветка нормально добавляется, я и так о этом знаю, потомучто если перезапустить программу, она становится видна. Совершенно не понимаю, почему ее сразу не становится видно.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: nitro2005 от Октябрь 27, 2010, 15:15
Может быть есть прокси-модель сверху, у которой dynamicSortFilter - false?


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 15:21
Может быть есть прокси-модель сверху, у которой dynamicSortFilter - false?

Нет, всё примитивно - вид QTreeView, подключена модель в виде наследника от QAbstractItemModel.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 15:26
Самое интересное, что если в конце дать команду

Код:
knowTree->reset();

то новая ветка становится видна. Но при этом "схлопываются" все распахнутые пользователем ветки, а это очень большое неудобство для пользователя.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: nitro2005 от Октябрь 27, 2010, 15:29
Тогда не знаю... могу только посоветовать создать функцию для вставки записи целиком внутри класса модели, как по учебнику:
Код:
QMyItem * KnowTreeModel::addItem(QMyItem *parent, ...)
{
...
  beginInsertRows(...);
  ...
  endInsertRows();
}
может она правильно генерит события только когда обновление идет одним блоком внутри класса, без возможности обработки каких-либо сторонних сигналов в промежутках...


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 15:38
Тогда не знаю... могу только посоветовать создать функцию для вставки записи целиком внутри класса модели

Вот что я выяснил. Отрисовка новой ветки происходит, если добавление идет к "обычной" ветке. А если идет добавление к корню, то, новую созданную ветку невидно.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 15:51
Корневой элемент, согласно документации - это элемент, у которого QModelIndex невалидный. Может, в этом дело? Но как же тогда добавлять ветки к корню, чтобы происходило обновление на экране?


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: nitro2005 от Октябрь 27, 2010, 15:54
А как вы добавляете к корню? Судя по коду у вас вообще должно вылетать при этом:
Код:
int item_rows=item->childCount();
ведь item при этом будет NULL.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 15:57
А как вы добавляете к корню? Судя по коду у вас вообще должно вылетать при этом:
Код:
int item_rows=item->childCount();
ведь item при этом будет NULL.

Я неправильно сказал. Корень - это элемент, у которого QModelIndex для свойства parent невалидный. У самого корня QModelIndex валидный (коль мне в дебаге показывает, сколько веток в корне есть). Почему тогда при добавлении к корню не происходит отрисовки новой ветки - неясно.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: nitro2005 от Октябрь 27, 2010, 16:10
ради эксперимента можно сделать emit layoutChanged().
и все равно непонятно как вы к корню элементы добавляете (имеется ввиду первый уровень)...


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: xintrea от Октябрь 27, 2010, 16:29
В общем, я переделал - отказался от beginInsertRows_middle() / endInsertRows_middle(), сделал paste_subbranch() приватным, добавив в knowTreeModel публичные функции:

Код
C++ (Qt)
// Добавление новой подветки к указанной ветке из буфера обмена
void KnowTreeModel::paste_new_child_branch(const QModelIndex &index, clipbbranch *subbranch)
{
// Получение ссылки на Item элемент по QModelIndex
TreeItem *parent=getItem(index);
 
beginInsertRows(index, parent->childCount(), parent->childCount());
paste_subbranch(parent, (clipbbranch *)subbranch);
endInsertRows();
}
 
 
void KnowTreeModel::paste_new_sibling_branch(const QModelIndex &index, clipbbranch *subbranch)
{
// Получение ссылки на родительский Item элемент по QModelIndex
TreeItem *current=getItem(index);
TreeItem *parent=current->parent();
 
beginInsertRows(index.parent(), parent->childCount(), parent->childCount());
paste_subbranch(parent, (clipbbranch *)subbranch);
endInsertRows();
}

И все заработало. Видимо, между beginInsertRows()/endInsertRows() нельзя делать какие-то действия, м.б. выходить из кода класса, не знаю. Поэтому и глючило с корнем. Впринципе, в коде ничего не изменилось, просто все действия перенёс внутрь кода модели.


Название: Re: [Туплю в последнее время] Увидеть новую ветку в QTreeView
Отправлено: pethead от Октябрь 28, 2010, 04:03
отметьте тему как решенную.
спасибо.