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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Как корректно отражать изменения списка в ListWidget?  (Прочитано 7012 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Апрель 22, 2019, 18:10 »

Есть у меня QML ListWidget, который связан с QQuickWidget (см. предыдущую тему с примером). Сейчас он заполняется, всё работает. Но список не постоянный - элементы могут удаляться и добавляться. Сейчас не ясно как корректно обрабатывать эти изменения списка чтобы не было memory leak и избыточного копирования. То есть после такой привязки:

Код:
    QList<QObject*> notebook;
.....
    rootContext()->setContextProperty("SomeList",QVariant::fromValue(notebook));
    setSource(QUrl("qrc:/listview.qml")); // здесь заданы параметры отображения ListView

Нужно ли что-то делать с QQuickWidget в котором это происходит, или с контекстом, или ещё с чем-нибудь, если содержимое notebook[] меняется?

И сразу ещё такой вопрос - если необходимо изменить отображение списка, достаточно ли установить другой

    setSource(QUrl("qrc:/listview2.qml"));

в котором элементы списка изображаются иначе? Или это надо делать по-другому?
« Последнее редактирование: Май 14, 2019, 22:06 от Гурман » Записан

2^7-1 == 127, задумайтесь...
clingerwinger
Новичок

Offline Offline

Сообщений: 7


Просмотр профиля
« Ответ #1 : Апрель 23, 2019, 15:10 »

Цитировать
Нужно ли что-то делать с QQuickWidget в котором это происходит, или с контекстом, или ещё с чем-нибудь, если содержимое notebook[] меняется?
Правильно будет вообще на сторону QML прокидывать модель. Унаследоваться от QAbstractListModel и сделать все как в документации. Если этот вариант не устраивает то может прокатить следующее:
* обновить контекстное свойство так же через setContextProperty;
* сказать вьюхе что модель изменилась, например view.modelChanged();

Цитировать
И сразу ещё такой вопрос - если необходимо изменить отображение списка
Правильно будет изменить делегат у вьюхи и использовать для этого Component {}
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Апрель 23, 2019, 15:38 »

Цитировать
И сразу ещё такой вопрос - если необходимо изменить отображение списка
Правильно будет изменить делегат у вьюхи и использовать для этого Component {}
Мне это надо делать из C++ кода. Я не знаю другой способ поменять делегата, кроме как подставить другой .qml файл, в котором такой же ListView имеет делегата с другими параметрами.
Записан

2^7-1 == 127, задумайтесь...
clingerwinger
Новичок

Offline Offline

Сообщений: 7


Просмотр профиля
« Ответ #3 : Апрель 23, 2019, 18:12 »

Описываете делегаты, желательно в отдельных файлах. Там где вью лежит объявляете их в качестве компонент:

Код:
...
ListView {
    id: view
    ...
    delegate: defaultComponent
}
...
Component
{
    id: defaultComponent
    DefaultDelegate {
        // Здесь можно объявлять дополнительные свойства, например onClicked: {...}
    }
}

Component
{
    id: awesomeComponent
    AwesomeDelegate { }
}
Далее можно менять свойство delegate у вьюхи и указывать нужные идентификаторы компонент.

По поводу вызова из C++: тут в целом зависит от приложения и архитектуры, но самый быстрый наколеночный вариант - пробросить указатель на некий QObject в сторону QML так же через setContextProperty и на стороне QML ловить сигналы через Connections:
Код:
Connections {
    target: myContextPropertyObject
    onMySignal: {
        if (signalParametr == true) {
            view.delegate = awesomeComponent;
        }
    }
}
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #4 : Апрель 23, 2019, 22:43 »

Примерно понятно. Ещё бы примеров толковых, а то в документации нет нифига.
Записан

2^7-1 == 127, задумайтесь...
clingerwinger
Новичок

Offline Offline

Сообщений: 7


Просмотр профиля
« Ответ #5 : Апрель 24, 2019, 12:16 »

Вполне себе отличная статья.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Май 07, 2019, 23:11 »

Что-то я влип в какую-то непонятку... Как написано в статье по ссылке из предыдущего сообщения, передёргиваю QQmlContext::setContextProperty() при изменении модели:

Код:
void MainList::receiveSheet(QList<QObject*>& sheet)
{
    rootContext()->setContextProperty("MainList",QVariant::fromValue(sheet));
    setSource(QUrl( sortview[sortOrder] ));
}

если список изменился только внутри, то есть переставлены элементы при сортировке, или если в список добавлены новые элементы - всё нормально, работает как ожидается. Но если в списке удалён элемент, то падает где-то внутри setContextProperty(). Qt собран без отладочной информации, не могу посмотреть что не так происходит внутри него. Вижу только в отладчике что сам список в порядке. Более того - перед передачей функции receiveSheet() он сохраняется в файл в текстовом виде, каждая запись сохраняется поэлементно - и там всё нормально. Это подтверждается тем, что при перезапуске приложения список загружается и корректно отображается - после этого же вызова receiveSheet(). Но падает после удаления элемента упорно в одном месте и на ПК, и на Android девайсе, значит ошибка не наведённая (типа порчи стека или кучи). И не имеет отношения к старым модулям из сборок - на ПК впервые собрал с отладчиком. Падает при любой длине списка - и при 0-й, и при не 0-й. Но самое обидное, что вчера... всё работало. Сегодня только добавил одно поле QString в модель, все остальные действия были с другими частями проекта, не влияющими на эту.

Добавляются элементы в список
Код:
    collection.insert( collection.begin(), new element(item, this) ); // this задаёт в элементе родителя
удаляются соответственно
Код:
    delete collection.takeAt( index );
то есть, ничего особенного. Если не вызывать setContextProperty(), то все внутренние функции со списком нормально работают, то есть он явно консистентен.

Вообще из-за чего в принципе может падать setContextProperty()? Поковырял ещё - в отладчике видно что падает внутри QQmlDelegateModel::release(QObject*), вокруг него неизвестные вызовы.
« Последнее редактирование: Май 07, 2019, 23:22 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #7 : Май 08, 2019, 13:35 »

С удалением падение не связано, проехали...
Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #8 : Май 27, 2019, 23:29 »

up...

Увы, поторопился. Всё-таки проблема с удалением. Чтобы не путать - создам отдельную тему.
Записан

2^7-1 == 127, задумайтесь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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