Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы редактирования DOM модели
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
JohnZ
В прицепе мин. проект, демонстрирующий проблемы редактирования.
ехе-шник там-же ... Проблемы в диалоге редактирования таблицы (через модель !).
Для того, чтобы к нему добраться, нужно в открытом конфиге (прилагается)
пройти по дереву от корня /->metadata->catalogues-> далее выбрать любой
справочник ( catalogue ) и в нём DblClick на таблице ( element ).
Появится диалог редактирования таблицы. Вопросы ...

1. В диалоге реализовано удаление поля, кнопка Del.
Сделано по подобию примера editabletreemodel.
После удаления, в bool DomItem::removeChildrens(int position, int count)
добавлена очистка хэш-а childItems.clear(), т.к. без этого
нет отоббражения действия в TreeView-e за диалогом, при развёрнутом
дереве полей таблицы.
В принципе к функции удаления претензий нет, работает отлично,
но правомочна-ли очистка хэш-а в плане утечек памяти ?
Ведь указатели на DomItem-ы хранятся только в хэше, а операция
QHash::clear() для QHash<int,DomItem*> childItems; не чистит хранимые
указатели на DomItem *, которые созданы операцией new !?
Если это действительно так, подскажите плз правильную реализацию ...

2. Реализация добавления поля аналогична удалению, в проект не ложил,
т.к. там понятно, через отдельный диалог.
Проблема в реализации bool swapChildrens(int pos1, int pos2);
Для добавления и удаления поля в модели есть соотв-щие ф-ции
    beginInsertRows(parent, position, position + rows - 1);   // !!!
    success = parentItem->insertChildrens(position, rows);
    endInsertRows();      // !!!

и
    beginRemoveRows(parent, position, position + rows - 1);   // !!!
    success = parentItem->removeChildrens(position, rows);
    endRemoveRows();   // !!!

Но в модели нет функций
beginSwapRows(parent, position, position + 1);
endSwapRows();
Как это можно реализовать (с отображением в TreeView-e), как в случае с удалением ?

3. Почему при открытии диалога, строка выбора в TreeView-e скачет хз куда ?
Странно это потому, что в оригинальном проекте, когда TreeView является
MdiChild-ом, такого не наблюдается ... Это так, из спортивного интереса :-)

Заранее благодарен за помощь.
lanz
1. Хэш никак с этим не связан. У меня все удаляется даже если закоментарить clear()
Память течет, именно потому что вы сказали.
Уберите хэш вообще, насовсем. Здесь он не нужен пока, только все запутывает.
Утекает вот отсюда:
    if (i >= 0 && i < domNode.childNodes().count()) {
        QDomNode childNode = domNode.childNodes().item(i);
        DomItem *childItem = new DomItem(childNode, i, this);
        childItems[i] = childItem;
        return childItem;
    }


Зачем вам параллельная иерархия DomItem которую вы пересоздаете каждый раз когда не найден элемент в хэше? Модель может работать и с кутешным DOM-деревом. Тоже сильно все упростит.

2. http://qt-project.org/doc/qt-4.8/qabstract...l#beginMoveRows
Или можете просто вызвать dataChanged для обоих строк после того как поменяете их внутри своей модели.

3. У меня все работает :lol: Не скачет.
JohnZ
Цитата(lanz @ 26.11.2014, 23:13) *
1. Хэш никак с этим не связан. У меня все удаляется даже если закоментарить clear()

Если закоментарить clear(), то нет "динамики", изменения в дереве будут видны только
после закрытия диалога. Если он есть, то изменения видны даже ЗА диалогом !
Цитата
Память течет, именно потому что вы сказали.
Уберите хэш вообще, насовсем. Здесь он не нужен пока, только все запутывает.

Хм ... Я об этом даже не задумывался, надо обмозговать ... Может ты и прав ...

Цитата
Утекает вот отсюда:
    if (i >= 0 && i < domNode.childNodes().count()) {
        QDomNode childNode = domNode.childNodes().item(i);
        DomItem *childItem = new DomItem(childNode, i, this);
        childItems[i] = childItem;
        return childItem;
    }

Всё правильно, я именно об этом "new" и спрашивал. Я уже пробовал вручную чистить элементы из хэш-а,
удаляя вначале все DomItem * и затем childItems.clear(), - вообще вылетает в ошибку доступа к "мусорной"
памяти при перестройке модели, откуда-то из глубин dll-ки ... Даже студия затыкается :-(

Цитата
Зачем вам параллельная иерархия DomItem которую вы пересоздаете каждый раз когда не найден элемент в хэше?

В QT-шном примере так было сделано. Я взял за основу предполагая, что это наилучший способ работы с DOM-деревом.
Кроме того, оказалось просто расширить эту структуру (DomItem), добавляя элементы для своих нужд ( IDD, IDС и т.д. )

Цитата
Модель может работать и с кутешным DOM-деревом. Тоже сильно все упростит.

А вот тут поподробнее можно ?
Начиная с какой версии QT есть такая фича ? (у меня 4.5.3)
Примерчик _редактируемой_ DOM-модели в TreeView есть ?
Хотя это и повлечёт солидную переделку проекта, но я за упрощение !
Подскажи где копать, т.е. что брать за основу ? (по аналогии с simpledommodel)
Совсем с нуля опять начинать не хоцца ...

Цитата
2. http://qt-project.org/doc/qt-4.8/qabstract...l#beginMoveRows
Или можете просто вызвать dataChanged для обоих строк после того как поменяете их внутри своей модели.

beginMoveRows - Дык это начиная с 4.6.0. Видимо придётся переходить на 4.6.х Жаль ...
Линуксы 4-6 летней давности, работающие и поныне на "слабых" машинах, собраны на версии 4.3.х ... 4.5.х.

Цитата
3. У меня все работает :lol: Не скачет.

Спишем на глюк QTreeView в SDI :D

lanz, Благодарю за помощь !
lanz
Цитата(JohnZ @ 27.11.2014, 17:57) *
после закрытия диалога. Если он есть, то изменения видны даже ЗА диалогом !

Тут проблема в том что после удаления из списка(в модели списка) элементы идут так:
1234 -> 123 (и это какой бы мы элемент ни удалили)
А в хэшк зависит от того какой элемент мы удаляем
1234 -> 123 (если 4)
1234 -> 234 (если 1)
и т.д.
Поэтому переформирование хэша помогает.
Почему работало когда ты закрывал диалог: шло обновление и он перебирал все строки. Когда доходил до той которой нет, весь хэш обновлялся и дальше шло все по порядку.
Выброси хэш, сразу станет сильно легче :lol:

Цитата
А вот тут поподробнее можно ?
Начиная с какой версии QT есть такая фича ? (у меня 4.5.3)
Примерчик _редактируемой_ DOM-модели в TreeView есть ?
Хотя это и повлечёт солидную переделку проекта, но я за упрощение !
Подскажи где копать, т.е. что брать за основу ? (по аналогии с simpledommodel)
Совсем с нуля опять начинать не хоцца ...

Имел ввиду QDomNode и сотоварищей. Ты же по сути строишь дублирующую структуру.

Цитата
beginMoveRows - Дык это начиная с 4.6.0. Видимо придётся переходить на 4.6.х Жаль ...

Можно просто вызвать dataChanged для этих двух строк, эффект будет тот же самый.

Цитата
Спишем на глюк QTreeView в SDI :D

У меня пятый кутэ, поэтому всякие могут быть разночтения. Сложно отделить такие детали.
JohnZ
Цитата(lanz @ 27.11.2014, 22:38) *
Почему работало когда ты закрывал диалог: шло обновление и он перебирал все строки. Когда доходил до той которой нет,
весь хэш обновлялся и дальше шло все по порядку. Выброси хэш, сразу станет сильно легче :lol:

Т.е. нужно переработать уже имеющуюся модель, но без использования хэш-а и DomItem * ? Так ?
Или ты имел в виду заменить хэш списком ?

И по поводу хэша, - DomItem только в хэш-е и хранятся ! По другому как ?
Фактически DomItem это "аналог" QTreeViewItem, построенный над QDomNode, который показывает QTreeView.

Цитата
Цитата
А вот тут поподробнее можно ?

Имел ввиду QDomNode и сотоварищей. Ты же по сути строишь дублирующую структуру.

Может DomItem ? Без дублирующей структуры возможно, если существует модель типа QDirModel но для xml-я.
Есть такая ? В 4.5.3 я такой не нашёл, поэтому применил эту. Может в версиях выше есть такая ?

Цитата
Цитата
beginMoveRows - Дык это начиная с 4.6.0. Видимо придётся переходить на 4.6.х Жаль ...

Можно просто вызвать dataChanged для этих двух строк, эффект будет тот же самый.

Спасибо, переделаю. О результате сообщу.
lanz
Цитата
Может DomItem ? Без дублирующей структуры возможно, если существует модель типа QDirModel но для xml-я.
Есть такая ? В 4.5.3 я такой не нашёл, поэтому применил эту. Может в версиях выше есть такая ?

Вот же она :lol:
http://doc.qt.digia.com/4.5/qdomnode.html
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.