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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Древовидная модель на основе QHash  (Прочитано 8179 раз)
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« : Август 12, 2008, 00:48 »

Необходимо засунуть существубщий древовидный класс (умеющий хранить или значение или дочерние ветви самого себя) в древовидную модель, посмотрел документацию, смутило то что там используется QList в качестве контейнера для хранения детей. Дело в том что при реализации древовидной модели необходимо определить ее метод parent, который в конце для создания индекса использует:

return createIndex(parentItem->row(), 0, parentItem);

и собственно класс реализующий дерево представленный в документации имеет следующее определение row

 int TreeItem::row() const
 {
     if (parentItem)
         return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));

     return 0;
 }

У меня фактически в качестве childItems выступает QHash а не QList - то есть IndexOf для него не может быть т.к. это неупорядоченный набор данных. Как правильно поступить?

Заранее спасибо!
Записан
ритт
Гость
« Ответ #1 : Август 12, 2008, 09:09 »

не совсем понимаю вопрос
QList - контейнер с доступом по индексу
QHash - контейнер с доступом по ключу

соответственно, для QHash будет не IndexOf, а key(v); для QMultiHash однозначного решения, наверное, не будет
к тому же, раз ты используешь хэш, вероятно в Т2 у тебя какие-то свои данные (или парент в лучшем случае)
если я прав, то следует изменить топологию, т.к. эта нефункциональна
например, хэш заменить на однонаправленный список (QList или QVector) и добавить хэш пар ров_модели=>индекс_списка
Записан
Alex03
Гость
« Ответ #2 : Август 12, 2008, 12:28 »

У меня фактически в качестве childItems выступает QHash а не QList - то есть IndexOf для него не может быть т.к. это неупорядоченный набор данных. Как правильно поступить?
break
Модель зачем нужна, для отображения в TreeView-хе?
Дети одного родителя в какой последовательности отображаться должны?
Если в любой, то думаю что внутри QHash данные всётаки упорядочены (в реализацию не смотрел, но наверняка там бинарное или более дерево). Итераторы есть, т.е. можно написать своё подобие indexOf().
Т.е. в int TreeItem::row() const
бежим от begin() до end() хэша парента, сравнивая с собой и параллельно считая номер row.
Ну а в
TreeItem *TreeItem::child(int row)
наоборот.

Всё это если данных в модели не много, и если отображать как попало, иначе доп навороты, и т.д.

PS Что является ключём хэша?
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #3 : Август 12, 2008, 18:05 »

всем спасибо за помощь, но я все еще не разобрался

модель действительно нужна для отображения в соответствующем классе представления - дерево

в принцепе порядок отображения полей в ветке родителя не имеет значения, правда он наверное не должен меняться в процессе работы программы

заменить QHash на QList нельзя т.к. изначально древовидный класс работает как многоуровневый ассоциативный массив (через этот самый QHash), его вообще писал не я мне дали интерфейс для реализации отображения содержимого класса. Ключем в классе является строка.

вариант с итераторами мне кажется отпадает т.к. в документации написано
...
QHash is unordered, so an iterator's sequence cannot be assumed to be predictable. If ordering by key is required, use a QMap.
...

поэтому вариант с собственной реализацией indexOf наверное отпадает т.к. в процессе работы у родительских веток появляются новые дети и удаляются старые - т.е. индекс будет недействительным.

Данных в дереве много - все ветки около 1000

если есть советы еще - пишите т.к. хочу разобраться

может его надо менять на QMap? - это стоящая плата за реализацию представления?
Записан
ритт
Гость
« Ответ #4 : Август 12, 2008, 18:59 »

опиши нормально что тебе требуется
чем тебя QHash не устраивает и зачем тебе сортировка? зачем тебе вообще индексОф?
и всё-таки QHash или QMultiHash? - от этого зависит конкретная реализация
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #5 : Август 12, 2008, 19:24 »

вроде понятно написал - есть готовый компонент - древовидный ассоциативный массив - он внутри осонован на QHash (про QMultiHash) я ничего не говорил

его надо с помощью технологии модель представление выводить на экран - IndexOf нужен для определения свойства ROW для этой самой модели дерева
Записан
ритт
Гость
« Ответ #6 : Август 12, 2008, 19:50 »

ну, блин...если ключ уникальный, то сделай доп.хэш ключ=>ров и индексОф нах не нужен
в чём непосредственно вопрос-то?
Записан
Alex03
Гость
« Ответ #7 : Август 13, 2008, 06:23 »

вариант с итераторами мне кажется отпадает т.к. в документации написано
Цитировать
QHash is unordered, so an iterator's sequence cannot be assumed to be predictable. If ordering by key is required, use a QMap.

поэтому вариант с собственной реализацией indexOf наверное отпадает т.к. в процессе работы у родительских веток появляются новые дети и удаляются старые - т.е. индекс будет недействительным.
При модификациях модели индексы становятся недействительными не зависимо от того что используется (QList/QHash или чтото ещё).
Т.е. если реализовать примерно так (на примере всё того же Simple Tree Model Example)
Код:
int TreeItem::row() const
{
    if(!parentItem)
        return 0;
    int nRet = 0;

    QHash<QString, TreeItem*>::const_iterator i = childItems.constBegin();
    while(i != childItems.constEnd())
    {
        if(i.value() == const_cast<TreeItem*>(this))
            return nRet;
        i++;
    }
    // !!!Ну очень интересно! У Парента нет чилда this!!!
    return 0;
}

TreeItem *TreeItem::child(int row)
{
    QHash<QString, TreeItem*>::iterator i = childItems.begin();
    while(i != childItems.end())
    {
        if(!row)
            return i.value();
        row--;
        i++;
    }
    // !!!По идее этого не д.б. никогда!!!
    return 0;
//    return new TreeItem();
}
То должно всё работать, другое дело что при модификациях возможено изменение порядка немодифицируемых строк, т.е. невыполнение
в принцепе порядок отображения полей в ветке родителя не имеет значения, правда он наверное не должен меняться в процессе работы программы

Цитировать
может его надо менять на QMap? - это стоящая плата за реализацию представления?
Можно у QMap-а использовать в качество ключа uint, а все обращения по ключу делать через qHash(keyString).
Т.е. по сути получится тот же QHash, только с упорядочиванием по qHash(keyString).

Но... Беганье циклами по большим QHash-ам, QMap-ам (Да и QList-ам тоже) довольно непроизводительно, можно рядом с QHash-ем, (QMap-ом, QList-ом и т.д.) положить, например, QMap<int, TreeItem*> (точнее т.к. row от нуля до n, то лучше видимо QList/QVector<TreeItem*>), а в самом TreeItem добавить int row, и модифицировать их в соответствии с модификацией данных.

« Последнее редактирование: Август 13, 2008, 07:06 от Alex03 » Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #8 : Август 15, 2008, 12:43 »

Цитировать
ну, блин...если ключ уникальный, то сделай доп.хэш ключ=>ров и индексОф нах не нужен

Наверное это самый правильный вариант, причем доп.хэш ключ=>ров хочется хранить в модели т.к. сам класс данных никакого отношения к row не имеет

Вариант с перебором итераторов мне кажется 100% нерабочим...
Записан
ритт
Гость
« Ответ #9 : Август 15, 2008, 14:50 »

естественно, хранить в модели
люое кеширование данных модели правильнее всего проводить в самой модели
Записан
Alex03
Гость
« Ответ #10 : Август 18, 2008, 07:36 »

Цитировать
ну, блин...если ключ уникальный, то сделай доп.хэш ключ=>ров и индексОф нах не нужен
Наверное это самый правильный вариант, причем доп.хэш ключ=>ров хочется хранить в модели т.к. сам класс данных никакого
отношения к row не имеет

1. А у Вас точно ключи уникальные? В соседних ветках нет одинаковых?
2. Помимо ключ=>ров, нужно ещё и row->TreeItem для соответствующего parent-а (TreeItem).

Цитировать
Вариант с перебором итераторов мне кажется 100% нерабочим...
Я думаю что он рабочий, но м.б. не оптимальный, и при изменениях может меняться последовательность веток/листьев в ветке/стволе.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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