Russian Qt Forum
Ноябрь 01, 2024, 07:30
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Model-View (MV)
>
QAbstractItemModel + QTreeView + обновление в модели по ключу id + key [РЕШЕНО]
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: QAbstractItemModel + QTreeView + обновление в модели по ключу id + key [РЕШЕНО] (Прочитано 8007 раз)
vintik
Гость
QAbstractItemModel + QTreeView + обновление в модели по ключу id + key [РЕШЕНО]
«
:
Февраль 16, 2012, 19:29 »
Всем привет!
Проблема следующая. Есть куча данных. Их удобно представлять в виде дерева. Есть модель для дерева. Данные отображаются в QTreeView
Данные отображаемые в дереве - это некие ключи.
x
|------y1
| |-----1
| |-----2
|------y2
| |-----1
| |-----2
Есть внешний источник, который шлёт сигналы например следующего типа. Ключ номер <y2, 2> больше не живой - его нужно удалить (т.е нужно удалить подузел 2 в узле y2) .
Стандартная реализация модели предполагает при манипуляции с моделью использовать индексы
( bool QAbstractItemModel::removeRows ( int row, int count, const QModelIndex & parent = QModelIndex()) ).
Вопрос в том, как правильно и грамотно установить соответствие между приходящим ключом и индексом?
Первая мысль была такая: при создании нового узла в дереве (модели) - индекс (QModelIndex) сохранять в хеш используя ключ (тот самый <y2, 2>).
А потом когда нужно удалить узел - получать индекс из хеша по ключу. И по индексу удалять.
Но обнаружилась проблема - после удаления чего-либо из модели внутренняя индексация изменяется.
Т.е. если раньше по индексу createIndex(3, 0, root) были доступны одни данные, то после
removeRows(2, 0, QModelIndex())
по индексу createIndex(3, 0, root) - уже другие данные.
И получается, что я ожидаю что по ключу <y2, 2> получу индекс для удаления именно этого узла из дерева - а на деле получаю индекс для удаления уже другого узла.
Думаю - есть какие-то иные стандартизированные способы для решения проблемы, подскажите куда копать?
«
Последнее редактирование: Март 03, 2012, 10:01 от vintik
»
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #1 :
Февраль 24, 2012, 09:37 »
значит вот что получилось - два способа:
1. Вообще забить на хранение соответствия между приходящим ключом и индексом. Воспользоваться методом QAbstractItemModel::match для поиска индекса листа в котором хранится y2, а потом для уже для найденного индекса тем же методом искать индекс листа, в котором хранится 2. По полученному индексу осуществлять удаление.
+ ничего не надо нигде хранить
- если обращение к модели частое (мой случай), то на поиск конкретного листа уходит много времени.
2. Использовать QTreeWidget вместо QTreeView и самописной модели. В QTreeWidget лист представляет из себя объект класса QTreeWidgetItem. Указатель на этот объект можно сохранить в хеше по ключу (<y2, 2>). Удалять лист уже не по индексу, а по сохранённому указателю.
Плюсы и минусы диаметрально противоположны первому случаю.
Оба подхода достаточно поверхностны, так что если кто-то обладает опытом в решении подобных проблем, буду рад совету
Записан
Bepec
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #2 :
Февраль 24, 2012, 09:43 »
А что тебе мешает вообще представить это деревом в виде списка?
Тогда помоему будет вообще не проблема.
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #3 :
Февраль 24, 2012, 10:26 »
Если честно ничего не мешает)
Дерево красивше смотрится.
Если я правильно понял, то 1ый список - листья 1го уровня, 2ой список - листья 2го уровня. И так далее, сколько уровней вложений, столько и списков?
list1 | list2
y1 <-- current | 1
y2 | 2
И ещё вопрос, если я буду использовать свою модель для списка, то удаление из модели тоже только через индексы? Я правильно понимаю? Если да, то снова встаёт проблема - как удалять что либо из модели по ключу?
«
Последнее редактирование: Февраль 24, 2012, 10:37 от vintik
»
Записан
andrew.k
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #4 :
Февраль 24, 2012, 10:41 »
Цитата: vintik от Февраль 16, 2012, 19:29
Но обнаружилась проблема - после удаления чего-либо из модели внутренняя индексация изменяется.
Т.е. если раньше по индексу createIndex(3, 0, root) были доступны одни данные, то после
removeRows(2, 0, QModelIndex())
по индексу createIndex(3, 0, root) - уже другие данные.
И получается, что я ожидаю что по ключу <y2, 2> получу индекс для удаления именно этого узла из дерева - а на деле получаю индекс для удаления уже другого узла.
Ну так ты обновляй не только модель, но и хеш, где у тебя хранятся индексы. Только ту ветку, которая была затронута удалением.
Тогда удаление будет чуть подольше, а поиск быстрее.
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #5 :
Февраль 24, 2012, 11:29 »
Смотри, я правильно рассуждаю?
Индекс определяется 3мя параметрами (номер строки, номер колонки, родитель)
Приходит сигнал, в нём ключ, по ключу я определяю, что например индекс (3, 0, root) нужно удалить. Удаляю.
Потом мне нужно найти все элементы хэша, у которых в значении лежат индексы из диапазона [ (4, 0, root); (rowCount(root) - 1, 0, root) ] - номер строки нужно уменьшить на 1.
hash.insert(hash.key(createIndex(4, 0, root)), createIndex(3, 0, root))
hash.insert(hash.key(createIndex(5, 0, root)), createIndex(4, 0, root))
...
hash.insert(hash.key(createIndex(rowCount(root) - 1, 0, root)), createIndex(rowCount(root) - 1 - 1, 0, root))
«
Последнее редактирование: Февраль 24, 2012, 14:14 от vintik
»
Записан
andrew.k
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #6 :
Февраль 24, 2012, 14:11 »
что у тебя ключ в хеше? и что является твоим ключом?
я думал, что ключ в хеше это какой-то ид из бд, а значение это индекс модели.тебе надо обновить в хеше индексы всех новых, а один лишний наверное можно и не удалять.
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #7 :
Февраль 24, 2012, 14:22 »
да, ключ в хэше. ключ представляет из себя пару чисел типа int. Он приходит в виде сигнала от стороннего модуля. По нему я получаю данные и строю элементы дерева. Ну т.е. пришёл ключ <1,4> эт значит что у корня появляется лист 1 и у листа 1 появляется лист 4. А со временем приходит сигнал для этого же ключа, о том что его нужно удалить из дерева.
попробовал вариант выше предложенный - да работает, но катастрофически долго!!! hash.key() ужасно долго отрабатывает
Записан
andrew.k
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #8 :
Февраль 24, 2012, 16:32 »
Цитата: vintik от Февраль 24, 2012, 14:22
да, ключ в хэше. ключ представляет из себя пару чисел типа int. Он приходит в виде сигнала от стороннего модуля. По нему я получаю данные и строю элементы дерева. Ну т.е. пришёл ключ <1,4> эт значит что у корня появляется лист 1 и у листа 1 появляется лист 4. А
Т.е. все листья имеют уникальный индекс?
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #9 :
Февраль 26, 2012, 10:00 »
Цитата: andrew.k от Февраль 24, 2012, 16:32
Т.е. все листья имеют уникальный индекс?
да, именно так
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #10 :
Февраль 26, 2012, 14:02 »
Эта проблема (индексы "уплывают" при вставке/удалении) возникает и без всякого model-view. Мне неизвестен какой-то общий метод. В дополнение к сказанному выше (если все же хочется работать по индексу)
- если удаление сосредоточено в одном месте, то удаляющий имеет ввиду смещение индексов
- то же но чуть в профиль: отложить удаление и (пока) маркировать doomed элемент (часто занося его в доп контейнер). Затем в какой-то момент удалить физически и переиндексироваться
Записан
Tonal
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #11 :
Февраль 27, 2012, 11:36 »
Вроде всё решается вполне просто:
После удаления узла выносишь из хеша его и его детей и обновляешь в индексы его братьев снизу.
Я использую beginRemoveRows endRemoveRows + несколько внутренних кешей для ускорения.
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #12 :
Февраль 27, 2012, 16:38 »
Цитата: Tonal от Февраль 27, 2012, 11:36
Вроде всё решается вполне просто:
После удаления узла выносишь из хеша его и его детей и обновляешь в индексы его братьев снизу.
Я использую beginRemoveRows endRemoveRows + несколько внутренних кешей для ускорения.
Суть ясна, но вот немного бы пояснения про внутренние кешы для ускорения, может пример какой-нить есть))
Записан
vintik
Гость
Re: QAbstractItemModel + QTreeView + обновление данных в модели по ключу + id + key
«
Ответ #13 :
Март 03, 2012, 10:00 »
Чтобы как-то завершить тему, скажу, что остановился на 2ом варианте из второго поста
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...