Реклама

[QML] Loader не очищает закрытый фрагмент, когда другой фрагмент открытый

qtquick, qt 5.7, qml

Всем доброго времени суток.

Проблема вот в чем: есть Loader, есть фрагменты (Fragment1.qml, Fragment2.qml, Fragment3.qml, …).
Если находиться на фрагменте3, то элементы с фрагмента 2 будут доступны на фрагменте3. Не в плане видимости. Фрагмент3 будет показывать те “виджеты” которые на нем установлены. Также и на других Фрагментах. Но сами “виджеты” будут доступны с других компонентов. Как будто они невидимые

За основу брался проект NavigationDrawer

  • #
  • 8 декабря 2016 г. 4:27

Добрый день.

Показывайте ваш программный код.

Здравствуйте, Евгений.
А какой программный код? Он такой же как и в Вашем примере.

Я же так понимаю, что проблема в Loader’е?

Loader {
        id: loader
        anchors.top: menuRect.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        source: "Fragment4.qml"
 
        //Функция для смены содержимого Loader
        function loadFragment(index){
 
            switch(index){
            case 0:
                loader.source = "Fragment1.qml"
                break;
            case 1:
                loader.source = "Fragment2.qml"
                break;
            case 2:
                loader.source = "Fragment3.qml"
                break;
            case 3:
                loader.source = "Fragment4.qml"
                break;
            case 4:
                loader.source = "Fragment5.qml"
                break;
            default:
                loader.source = "Fragment1.qml"
                break;
            }
        }

Я пытаюсь понять формулировку вашего вопроса.
В чём выражается доступность элементов из одного фрагмента в другом? Что значит доступность из компонентов?

В QML иерархическая структура элементов в виде дерева. При этом если компонент не добавлен явно допустим в main.qml или другой файл который добавлен в main.qml, то элементы этого компонента могут быть доступны, когда он загружен в Loader или в StackView. Но при этом автодополнение кода работать не будет, поскольку фактически без запуска проекта не представляется возможным сказать, какой именно элемент находится в Loader. То есть с точки зрения написания кода, мы пишем код вслепую.

Для меня эта невидимость элементов представляется таким образом. Я сталкивался именно с таким поведением. Но я немного не догоняю, что Вы подразумеваете под этим. Опишите подробнее и по возможности на примерах кода. Как ведёт себя приложение.

Что значит, что крутилкой можно управлять с другого фрагмента, но при этом её не видно? Вам нужно, чтобы она была видна?

Евгений, смотрите: во вложении есть 2 скриншота.
На фрагменте 2 видно кнопки, лейбы и т.д. и если навести курсор на приблизительное местоположение “крутилки”, в то время когда загружен Фрагмент 2, и покрутить её, то обнаружиться что данные по модбасу передались. А именно прошла регулировка (та крутилка работает в качестве регулировки устройства).

Получается что Loader не освобождает память и не выгружает предыдущие фрагменты. А при запуске программы он все фрагменты загружает и держит в памяти.

То-есть если переключиться с одного фрагмента на другой, то предыдущий фрагмент он не выгружает с памяти

Не могли бы один момент проверить тогда?
При переключении фрагментов нет ли утечек памяти? То есть попереключать фрагменты: 1-2-3-1-2-1-3-1 и т.д.
Растёт ли в данном случае потребление памяти постоянно или останавливается всё-таки на определённом уровне?

По ходу он всё-таки кое-что кеширует от предыдущего фрагмента, но он должен очищать память, если загружен другой фрагмент.

По ходу он всё-таки кое-что кеширует от предыдущего фрагмента, но он должен очищать память, если загружен другой фрагмент.

Всё таки после загрузки другого фрагмента не очищает память. Нужно избавиться от кеша как-то. Или же отключить кеширование, или не кеширование и загрузку всех фрагментов при запуске программы.

Только не могу понять: Как это сделать?

Я вот что подумал, а может Вам попробовать использовать StackView? Например вот такой вариант. В принципе тоже самое будет, но более функциональное.

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
 
ApplicationWindow {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
 
    Drawer {
        width: Math.min(window.width, window.height) / 3 * 2
        height: window.height
 
        ListView {
            anchors.fill: parent
 
            delegate: ItemDelegate {
                padding: 0
                width: parent.width
                height: 48
                highlighted: ListView.isCurrentItem
                text: model.text
 
                onClicked: {
                    stackView.replace(model.source)
                }
            }
 
            model: ListModel {
                ListElement { text: "Page 1"; source: "qrc:/Page1.qml"; }
                ListElement { text: "Page 2"; source: "qrc:/Page2.qml"; }
                ListElement { text: "Page 3"; source: "qrc:/Page3.qml"; }
            }
        }
    }
 
    StackView {
        id: stackView
        anchors.fill: parent
        initialItem: "qrc:/Page1.qml"
    }
}

 

Да, Евгений, вроде как недостаёт он соседний виджеты. Но поскольку та программа обросла уже некоторым другим кодом, то мне не удаётся корректно “портировать” код.

Можно попросить Вас принять участь в помощи написания этого кода?

С меня будет благодарность

У меня сейчас очень мало свободного времени.
Поэтому положительный ответ на Вашу просьбу весьма затруднителен.

Впрочем, глянуть код я могу, и если там не будет слишком много работы, то правки возможны. Но не раньше выходных, да и то от силы 1-2 часа смогу уделить этому.
Но нужно, чтобы проект был в репозитории, куда можно потом запушить изменения. Если такового нет, то посмотрите в сторону сервиса BitBucket. Там есть возможность создания закрытых репозиториев. Ну и система контроля версий должна быть Git.

  • EVILEG
  • #
  • Ответ был помечен как решение
  • 14 декабря 2016 г. 7:59

Отбой. Евгений, я нашел свою ошибку. Ваш новый код не понадобиться.
Вся проблема была лишь в одной строчке. Я в main.qml вызывал фрагмент Fragment3.qml. Просто в коде было написано fragment3{}
Я его там написал, потому что проводил некоторые манипуляции и после этого я забыл его стереть.

Спасибо Вам за помощь и отклик. Ждем новых уроков по QML. С меня благодарность. Успехов в программировании :)

Реклама

Ответы

Только авторизованные пользователи могут отвечать на форуме.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
  • Cheessy
  • 23 января 2018 г. 16:39

C++ - Тест 006. Перечисления

  • Результат 80 баллов
  • Очки рейтинга 4
  • Cheessy
  • 23 января 2018 г. 15:52

C++ - Тест 003. Условия и циклы

  • Результат 71 баллов
  • Очки рейтинга 1
  • Cheessy
  • 23 января 2018 г. 15:28

C++ - Тест 005. Структуры и Классы

  • Результат 66 баллов
  • Очки рейтинга -1
Последние комментарии
  • EVILEG
  • 22 января 2018 г. 8:56

QML - Урок 004. Сигналы и слоты в Qt QML

Так и будет передаваться. Это аргумент сигнала. void sendToQml(int count); Видите сигнатуру? аргумент называется count . Вот он и передаётся. А описывать в Q_PROP...

  • xintrea
  • 22 января 2018 г. 8:43

QML - Урок 004. Сигналы и слоты в Qt QML

Не понял, как будет передаваться значение count в QML, если нигде он не описан через Q_PROPERTY

  • EVILEG
  • 21 января 2018 г. 20:42

Qt/C++ - Урок 029. Изображение в базе данных в Qt – Сохранение и Восстановление

Добрый день! Подготовьте изображение к вставке в базу данных через bind, как сделано в методе insertIntoTable, в данном примере. Больше похоже на то, что вылетает неожидан...

  • Mark
  • 21 января 2018 г. 19:32

Qt/C++ - Урок 029. Изображение в базе данных в Qt – Сохранение и Восстановление

Перед этим приложение работало отлично, ошибка связана именно с добавлением данного поля

  • Mark
  • 21 января 2018 г. 19:31

Qt/C++ - Урок 029. Изображение в базе данных в Qt – Сохранение и Восстановление

также вот вывод  текста самого запроса "Insert into commands_one (name, seq, pic) values ('bnbvn','\n1. bvnb\n2. bvnb', �PNG\r\n\u001A\n );"

Сейчас обсуждают на форуме
  • EVILEG
  • 23 января 2018 г. 11:19

Как в QML наиболее правильно сделать ~50 копий изображения?

Добрый день! Вообще самое эффективное, чего я добивался в рамках QML - это отрисовка в рукопашную через OpenGL - это касается скорости отрисовки. Когда создаёте несколько изо...

256 строк в модели данных

Извиняюсь, нашел ответ тут http://www.qtcentre.org/threads/54533-QSqlQueryModel-%E2%80%98s-method-rowcount()-return-256 if(this->canFetchMore()){ this->fetchMore(); }...

  • EVILEG
  • 18 января 2018 г. 20:46

Как проверить доступность сервера

Тут скорее всего ситуативно, но по факту да, в большинстве задач можно обойтись и одним network менеджером

  • EVILEG
  • 18 января 2018 г. 20:46

QGraphicsScene

Как вариант умножать ключевые координаты, от которых вы строите весь панораму, на общую ширину панорамы и при прокрутке отталкиваться от этих кратных координат.

  • Ruslan
  • 18 января 2018 г. 11:51

Исключения. Потоки.

Все оказалось проще. Документацию то читал, но забыл нюансы. Не указывал в connect  тип подключения Qt::DirectConnection