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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Возможно ли добавление строк в корень QStandardItemModel с помощью insertRows()?  (Прочитано 1089 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 740



Просмотр профиля WWW
« : Декабрь 06, 2018, 13:44 »

Написал я конструктор модели, унаследованный от QStandardItemModel. Модель подразумевается древовидная. В нем shortcutManager.availableSection - просто QStringList с названиями разделов «верхнего» уровня:

Код:
ShortcutSettingsModel::ShortcutSettingsModel(QObject *parent) : QStandardItemModel(parent)
{
    // Создание разделов
    foreach(QString sectionName, shortcutManager.availableSection) {
        QStandardItem *sectionItem=new QStandardItem(sectionName);
        this->appendRow(sectionItem);
    }
}

Конструктор работает, строки в виде появляются.

А потом думаю: нет, эдак у меня память потечет, потому что если сделать clean() в деструкторе, то очистится модель, а удалятся ли из кучи вставленные в нее QStandardItem - неизвестно. Придется городить рекурсивную очистку элементов, ну его нафиг.

Поэтому переписал конструктор вот так:

Код:
ShortcutSettingsModel::ShortcutSettingsModel(QObject *parent) : QStandardItemModel(parent)
{
    // Создание разделов
    int nSection=shortcutManager.availableSection.size(); // Количество разделов

    this->insertRows(0, nSection, QModelIndex()); // Вставка строк для разделов

    for(int i=0; i<nSection; ++i) {
        QModelIndex index=this->index(i, 0);

        QString sectionName=shortcutManager.availableSection.at(i);
        this->setData(index, sectionName); // Установка значения строки
    }
}

Но с таким кодом строк дерева в виде не видно.

Я подозреваю, что проблема в методе insertRows(). Третьим параметром он принимает индекс элемента, для которого создаются «подчиненные» элементы. Проблема в том, в концепции QStandardItemModel нет специального индекса для корня дерева. Есть только невалидный индекс, и предполагается, что ячейки первого уровня просто имеют невалидный индекс родителя.

Тогда возникает вопрос: а как блин создать ячейки первого уровня, если insertRows() требует индекс корневого элемента, но у нас его нет? Я пробую указать невалидный индекс как QModelIndex(), это прокатывает при компиляции, но во время работы толку от этого индекса нет.

Еще заметил, что когда крутится цикл, конструкция

Код:
this->index(i, 0)

все время возвращает одно и тоже значение, несмотря на то, что i меняется.

Получается, что метод insertRows() невозможно применить для корня дерева, а можно применять только для элементов, которые уже есть в дереве. А как добавлять эти самые первичные элементы?
Записан

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

Сообщений: 726



Просмотр профиля
« Ответ #1 : Декабрь 06, 2018, 14:03 »

Сильно в суть темы не вникал.

Проблема в том, в концепции QStandardItemModel нет специального индекса для корня дерева. Есть только невалидный индекс, и предполагается, что ячейки первого уровня просто имеют невалидный индекс родителя.

QStandardItemModel::invisibleRootItem() не поможет? Ещё там в справке есть "An example usage of QStandardItemModel to create a tree".
Записан

Пока сам не сделаешь...
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 740



Просмотр профиля WWW
« Ответ #2 : Декабрь 06, 2018, 14:12 »

Нет, потому что у него "Note: Calling index() on the QStandardItem object retrieved from this function is not valid". То есть index() у этого элемента невалидный, и по сути, то же самое что вызов QModelIndex() (который дает невалидный индекс). То есть получить index, который бы указывал на корень дерева, через элемент invisibleRootItem() невозможно.

Ещё там в справке есть "An example usage of QStandardItemModel to create a tree".
В это примере как раз подход, который используется в первом конструкторе. И ни слова не говорится, надо ли уничтожать в деструкторе понаделанные через new элементы.
Записан

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

Сообщений: 740



Просмотр профиля WWW
« Ответ #3 : Декабрь 06, 2018, 15:08 »

Ага, вот тут есть ответ на то, что происходит с элементами, которые создаются через new и вставляются в модель:

Цитировать
Когда объект QStandardItem передаётся в QStandardItemModel , то права собственности на данные объекты передаются в модель. И при вызове метода clear модель автоматически удаляет эти объекты из памяти.

https://evileg.com/ru/post/221/

То есть, можно обойтись и первым конструктором.
Записан

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

Сообщений: 726



Просмотр профиля
« Ответ #4 : Декабрь 06, 2018, 15:17 »

Цитировать
Когда объект QStandardItem передаётся в QStandardItemModel , то права собственности на данные объекты передаются в модель. И при вызове метода clear модель автоматически удаляет эти объекты из памяти.

И ни слова не говорится, надо ли уничтожать в деструкторе понаделанные через new элементы.

В Qt это не удивительно Улыбающийся. Буквально вчера об этом говорили.
Записан

Пока сам не сделаешь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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