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

qtquick, qt 5.7, qml

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

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

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

0
The question is asked by the articleQML - Lesson 019. Navigation Drawer in Qt Qml Android

Do you like it? Share on social networks!

12
Evgenii Legotckoi
  • Dec. 8, 2016, 10:27 a.m.

Добрый день.

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

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

    Я же так понимаю, что проблема в 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.

                        ДЧ
                        • Dec. 14, 2016, 1:59 p.m.
                        • The answer was marked as a solution.

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

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

                          Comments

                          Only authorized users can post comments.
                          Please, Log in or Sign up
                          • Last comments
                          • AK
                            April 1, 2025, 11:41 a.m.
                            Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
                          • Evgenii Legotckoi
                            March 9, 2025, 9:02 p.m.
                            К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
                          • VP
                            March 9, 2025, 4:14 p.m.
                            Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
                          • ИМ
                            Nov. 22, 2024, 9:51 p.m.
                            Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                          • Evgenii Legotckoi
                            Oct. 31, 2024, 11:37 p.m.
                            Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup