Динамическое наполнение StackView QML
Не могу понять, как правильно динамически заполнять StackView в Qml...
У меня в qml описаны: ModuleTip1.qml, ModuleTip2.qml.
И есть main.qml, в котором находится StackView... Я хочу динамически запихивать в этот StackView в зависимости от типа - один из этих двух элементов, но так, чтобы при вызове метода StackView.pop() - вызывался и деструктор выталкиваемого объекта.
Проблема в том, что при StackView.pop - деструктор выталкиваемого объекта вызывается только в том случае, если объект создавался самим StackView-ом. И я не совсем пойму, как добиться такого поведения...
========
1-ПРИМЕР, как получается, но с недостатком (опишу ниже):
если я в main.qml создам
Component{id: tip1; ModuleTip1{}}
Component{id: tip2; ModuleTip2{}}
Тогда при StackView.push(tip1) - новый элемент создастся и при StackView.pop() вызовется и деструктор выталкиваемого объекта, но если этих типов модулей у меня будет 500? Столько компонентов прописывать еще и в main.qml как-то не хочется...
========
2-ПРИМЕР, где деструктор не вызывается:
дописал moduleCreation.js
- var component;
- var sprite;
- function createModule(qmlTip, parent) {
- component = Qt.createComponent(qmlTip);
- if (component.status == Component.Ready){
- return finishCreation(parent);
- }
- else{
- component.statusChanged.connect(finishCreation);
- }
- }
- function finishCreation(parent) {
- if (component.status == Component.Ready) {
- sprite = component.createObject(parent, {x: 100, y: 100});
- if (sprite == null) {
- console.log("Error creating object");
- }
- else{
- return sprite
- }
- } else if (component.status == Component.Error) {
- console.log("Error loading component:", component.errorString());
- }
- }
И заполняю StackView:
StackView.push(moduleCreation.createModule("ModuleTip1.qml", StackView))
StackView.push(moduleCreation.createModule("ModuleTip2.qml", StackView))
Но при вызове StackView.pop() не вызывается деструктор выталкиваемых объектов, а очень хочется, чтобы вызывался(((
Do you like it? Share on social networks!
- Last comments
- AKApril 1, 2025, 11:41 a.m.Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
- VPMarch 9, 2025, 4:14 p.m.Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
- ИМNov. 22, 2024, 9:51 p.m.Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
- Now discuss on the forum
- МАApril 1, 2025, 4:21 p.m.0ff763fe-4e50-455d-a3a6-5699c243b1a5_17_44_22_1.xml
- fFeb. 15, 2025, 1:46 p.m.Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
- Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
- Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
В QML есть сборщик мусора. Предполагаю, что во втором случае полное уничтожение объекта может вызываться позднее.
Так что попробуйте после вызова StackView.pop() сразу вызвать сборщик мусора через вызов функции gc() .
Так что, если это сработает, а также у вас нет причин в обязательном мгновенном вызове деструктора, то смысла дёргаться по этому поводу нет. Qt сам удалит объект полностью, когда сочтёт нужным в соответствии со своей логикой.
Попробовал... Вызов gc() не дал результата(((
Объекты продолжили свое существование и удалились только после того, как был удален родитель (в момент динамического создания объектов родителем указывался сам StackView)...
Но по факту это значит, что мой StackView наполняется ново-созданными объектами, раздуваясь в памяти. Память хоть и мизерная, но сам принцип такого поведения StackView меня не устраивает...
Вот и не пойму... Неужели какого-то типичного решения нет?
Вроде же достаточно стандартное поведение ожидается: "динамически засунул, тогда удаляй, когда выплевываешь"...
Я сделал немного иначе: в момент создания сохранил ссылку на объект, а потом тру ее методом .destroy()
Но все-равно странно как-то, что приходится самому руками тереть...
Я вот сейчас открыл документацию и прочитал
Так что поведение ожидаемое и странным не является, ибо описано в документации на этот метод. Документация
Проще говоря, внешнее создание объекта может предполагать использование объекта в других местах, либо кэширование. А значит, что удаление объекта при вызове метода pop() напротив является необоснованным действием
Ну так я это сразу и написал:
"Проблема в том, что при StackView.pop - деструктор выталкиваемого объекта вызывается только в том случае, если объект создавался самим StackView-ом. И я не совсем пойму, как добиться такого поведения..."
С компонентами - понятно... Но эти компоненты создавать надо самому...
А вот как создавать с помощью url-ов? Я чет не разобрался...
Ведь мои ModuleTip1.qml и тд файлы - это ведь и есть те самые урлы, которые нужно как-то этому StackView передать?
Во затупил)))
Спасибо за все)))
StackView.push("ModuleTip1.qml")
ну или в сложной иерархии StackView.push("qrc:/folder/ModuleTip1.qml")
и всего делов... Не пойму, почему сразу у меня не получилось...
StackView.push("qrc:/folder/ModuleTip1.qml", {x:100, y: 100}) - если нужны параметры