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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] Увидеть новую ветку в QTreeView  (Прочитано 6219 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« : Октябрь 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-представлении новые данные добавляются, а на экране новая подветка не появляется.

Вопрос. Почему так? Что нужно сделать, чтобы увидеть строку с новой подветкой?
« Последнее редактирование: Октябрь 28, 2010, 21:34 от xintrea » Записан

Собираю информацию по крупицам
http://webhamster.ru
nitro2005
Гость
« Ответ #1 : Октябрь 27, 2010, 14:57 »

Проверьте knowTreeModel->rowCount(item_index) до beginInsertRows и после endInsertRows.
Кроме того, какой номер колонки: item_index.column() - должен быть нуль.
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #2 : Октябрь 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

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

Собираю информацию по крупицам
http://webhamster.ru
nitro2005
Гость
« Ответ #3 : Октябрь 27, 2010, 15:15 »

Может быть есть прокси-модель сверху, у которой dynamicSortFilter - false?
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #4 : Октябрь 27, 2010, 15:21 »

Может быть есть прокси-модель сверху, у которой dynamicSortFilter - false?

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

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

Сообщений: 754



Просмотр профиля WWW
« Ответ #5 : Октябрь 27, 2010, 15:26 »

Самое интересное, что если в конце дать команду

Код:
knowTree->reset();

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

Собираю информацию по крупицам
http://webhamster.ru
nitro2005
Гость
« Ответ #6 : Октябрь 27, 2010, 15:29 »

Тогда не знаю... могу только посоветовать создать функцию для вставки записи целиком внутри класса модели, как по учебнику:
Код:
QMyItem * KnowTreeModel::addItem(QMyItem *parent, ...)
{
...
  beginInsertRows(...);
  ...
  endInsertRows();
}
может она правильно генерит события только когда обновление идет одним блоком внутри класса, без возможности обработки каких-либо сторонних сигналов в промежутках...
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #7 : Октябрь 27, 2010, 15:38 »

Тогда не знаю... могу только посоветовать создать функцию для вставки записи целиком внутри класса модели

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

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

Сообщений: 754



Просмотр профиля WWW
« Ответ #8 : Октябрь 27, 2010, 15:51 »

Корневой элемент, согласно документации - это элемент, у которого QModelIndex невалидный. Может, в этом дело? Но как же тогда добавлять ветки к корню, чтобы происходило обновление на экране?
Записан

Собираю информацию по крупицам
http://webhamster.ru
nitro2005
Гость
« Ответ #9 : Октябрь 27, 2010, 15:54 »

А как вы добавляете к корню? Судя по коду у вас вообще должно вылетать при этом:
Код:
int item_rows=item->childCount();
ведь item при этом будет NULL.
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #10 : Октябрь 27, 2010, 15:57 »

А как вы добавляете к корню? Судя по коду у вас вообще должно вылетать при этом:
Код:
int item_rows=item->childCount();
ведь item при этом будет NULL.

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

Собираю информацию по крупицам
http://webhamster.ru
nitro2005
Гость
« Ответ #11 : Октябрь 27, 2010, 16:10 »

ради эксперимента можно сделать emit layoutChanged().
и все равно непонятно как вы к корню элементы добавляете (имеется ввиду первый уровень)...
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #12 : Октябрь 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() нельзя делать какие-то действия, м.б. выходить из кода класса, не знаю. Поэтому и глючило с корнем. Впринципе, в коде ничего не изменилось, просто все действия перенёс внутрь кода модели.
« Последнее редактирование: Октябрь 28, 2010, 21:37 от xintrea » Записан

Собираю информацию по крупицам
http://webhamster.ru
pethead
Гость
« Ответ #13 : Октябрь 28, 2010, 04:03 »

отметьте тему как решенную.
спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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