ВЖ
Владимир Житковский23 января 2020 г. 13:29

Правильное удаление объектов из ++ модели ассоциированной со списком в QML

Qt, C++, QML, QObject, ListView

Доброго дня! Вопрос как правильно удалять данные из модели сделанной таким образом:
https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html пример с QObjectList-based Model.
В плюсовой части есть список QList lstData; в который добавляется структура типа

class Data: public QObject
{
    Q_OBJECT

    Q_PROPERTY(...)
  
    public:
        Data() {}

       ~Data()
        {
              qDebug() << "~Data";
        }

....

};

добавляется lstData.append(new Data());
после этого делается context->setContextProperty("M_Data", QVariant::fromValue(lstData));

в QML части:

ListView
{
      id: idTableBody
      anchors { fill: parent }                
      clip: true
      model: M_Data
}

и все вроде ок, когда я редактирую/добавляю данные в модель, а потом делаю обновление как написано по ссылке context->setContextProperty("M_Data", QVariant::fromValue(lstData));
интересности начинаются, когда я пытаюсь удалить данные..
чтобы удалить одну строку делаю так

for(int i = 0; i < lstData.count(); ++i)
    {
        auto *data= dynamic_cast<Data*>(lstData[i]);
        if(data)
        {
            if(data->getNumber() == delNumberData)
            {
                lstData.removeAt(i);
                delNumberReason = -1;
                return true;
            }
        }
    }

для удаления всех строк вызываю просто lstData.clear() и это работает, НО.. я не вижу, чтобы вызывался деструктор объекта!
removeAt(); и clear() вроде как и не должны его вызывать.. ок, тогда я делаю
delete lstData.takeAt(i); для удаления одной строчки и qDeleteAll(lstData); и для удаления всего списка и при этом деструктор вызывается с....(внимание!) обязательным крашем программы! :)
и вот собственно как это разрулить счастье, кто отвечает за освобождение памяти.. и как это правильно сделать?

P.S: Посдказали еще сделать деструктор virtual в Data, но это не сильно помогло в том плане, что оно крашется теперь не каждый раз, а как-то рандомно при вызове qDeleteAll(lstData). Да и виртуальный деструктор нужен в базовом классе, для корректного удаления производных классов через указатель на базовый. Базовым классом для моего класса Data является QObject, а у него деструктор виртуальный! Поэтому вроде как все должно работать было и без добавления virtual в мой класс Data.. но оно не работает

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

2
Evgenii Legotckoi
  • 24 января 2020 г. 3:24

Добрый день

Попробуйте использовать метод deleteLater() у объектов Data . В этом случае удаление происзодит немного позже, но уже тогда, когда другие части программы не ссылаются на объект и не используют его.

    ВЖ
    • 26 января 2020 г. 4:11
    • Ответ был помечен как решение.

    Да, спасибо порешалось таким образом:
    удаление одного

    for(int i = 0; i < lstData.count(); ++i)
    {
        auto *data= dynamic_cast<Data*>(lstData[i]);
        if(data)
        {
             if(data->getNumber() == delNumber)
             {
                 lstData[i]->deleteLater();
                 lstData.removeAt(i);
                 delNumber = -1;
                 context->setContextProperty("M_Data", QVariant::fromValue(lstData));
                 return true;
             }
        }
    }
    

    удаление всех

    context->setContextProperty("M_Data", QVariant::fromValue(QList<QObject*>()));
    qDeleteAll(lstData);
    lstData.clear();
    

      Комментарии

      Только авторизованные пользователи могут публиковать комментарии.
      Пожалуйста, авторизуйтесь или зарегистрируйтесь
      Г

      C++ - Тест 001. Первая программа и типы данных

      • Результат:66баллов,
      • Очки рейтинга-1
      t

      C++ - Тест 001. Первая программа и типы данных

      • Результат:33баллов,
      • Очки рейтинга-10
      t

      Qt - Тест 001. Сигналы и слоты

      • Результат:52баллов,
      • Очки рейтинга-4
      Последние комментарии
      G
      GoattRock3 сентября 2024 г. 20:50
      Как Копировать Файлы в Linux Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
      ВР
      Влад Русоков2 августа 2024 г. 8:47
      Как Копировать Файлы в Linux Screenshot_20240802-065123.png
      d
      dblas55 июля 2024 г. 18:02
      QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
      k
      kmssr9 февраля 2024 г. 2:43
      Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
      АК
      Анатолий Кононенко5 февраля 2024 г. 9:50
      Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
      Сейчас обсуждают на форуме
      Evgenii Legotckoi
      Evgenii Legotckoi24 июня 2024 г. 22:11
      добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
      F
      Fynjy22 июля 2024 г. 11:15
      при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
      BlinCT
      BlinCT25 июня 2024 г. 8:00
      Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
      BlinCT
      BlinCT5 мая 2024 г. 12:46
      Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
      Evgenii Legotckoi
      Evgenii Legotckoi2 мая 2024 г. 21:07
      Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

      Следите за нами в социальных сетях