Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Dynamic QML Page loader
Forum Updated to NodeBB v4.3 + New Features

Dynamic QML Page loader

Scheduled Pinned Locked Moved Solved QML and Qt Quick
15 Posts 4 Posters 6.4k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    CristianoNarcisiVidex
    wrote on 8 Apr 2019, 16:38 last edited by
    #1

    Hi all
    i am developing an application that has a lot of different pages. I don't want to create all of them as it gets started and then show only the one that is interacting with user. I would like to create and destroy QML objects as i need, creating a queue that allows me to keep trace of the pattern that the user has followed while using the software.
    I have though to create a C++ object for doing it ( i will name GuiTreeManager). It will be the only component able to load / destroy the pages. I am thinking to use the QQmlApplicationEngine for loading the pages, and to expose it as a singleton for all of them. I have hence some constrains to respect:

    • The QML must have a Window, which allow me to use the QQmlApplicationEngine
    • Expose the GuiTreeManager as singleton and connect the GUI QML events to a slot called "loadNewPage". it will have the url of the new page to be loaded as argumnet.
    • All the GUI QML items must have a method that allows the GuiTreeManager to close and destroy all of them ( i want to avoid any memory leakeage). I need something similar to an interfaces, that all the QML pages must impement.

    Let me pass to my questions.

    • First of all: does any other better way for doing what i need?

    • Does in QML exist something simialr to the interfaces

    • is it possible to call the destructor of a QML object?

    Thanks in advance and sorry for what i am asking for. I know that it could be a very silly question?

    Best Regards

    Cristiano Narcisi

    1 Reply Last reply
    0
    • S Offline
      S Offline
      shaan7
      wrote on 8 Apr 2019, 17:21 last edited by
      #2

      You might find StackView useful. You should be able push to Loaders onto the stack and then have the Loaders load your "page" UI. Once you're done with a page, you can set the Loader's active property to false and it will destroy the UI as you want.

      C 1 Reply Last reply 9 Apr 2019, 15:31
      1
      • S shaan7
        8 Apr 2019, 17:21

        You might find StackView useful. You should be able push to Loaders onto the stack and then have the Loaders load your "page" UI. Once you're done with a page, you can set the Loader's active property to false and it will destroy the UI as you want.

        C Offline
        C Offline
        CristianoNarcisiVidex
        wrote on 9 Apr 2019, 15:31 last edited by CristianoNarcisiVidex 4 Sept 2019, 16:27
        #3

        Thanks a lot @shaan7 . As you can understand, i am not so ecperienced with QML. I have just read something about StackView, and it seems to do what i was asking for. I am some doubt, that could be sounds very stupid for you.
        How can i create nested pages using it? I have download the touch application and only the first page can load the others and only from the main page the user can go back. It is not exactly what i am meaning.
        Do you understand?

        Let me add a snippet of code:

        Item {
            id: element1
            Loader
            {
                id: loader
                anchors.fill: parent
        
            }
        
            Text {
                id: element
                text: qsTr("First Element")
        
            }
        
            MouseArea
            {
                anchors.fill: parent
                onClicked:
                {
        
                    loader.setSource("SecondItem.qml")
                    loader.active = false
        
                }
            }
        
        }
        
        

        I iwould like that loader.setSource("SecondItem.qml") will create the new page for first ,and then will destroy itself!

        1 Reply Last reply
        0
        • S Offline
          S Offline
          shaan7
          wrote on 9 Apr 2019, 16:47 last edited by
          #4

          Hi,

          I think there is a good example for you in the New Project dialog in Qt Creator-
          0_1554828303847_Screenshot_20190409_221435.png

          This will give you an example app which has a StackView with two pages and you can navigate by using the menu or pressing Back-

          0_1554828401021_c24d866e-37a2-4a8d-8b17-143384c1889b-image.png

          Let me know if the example is still not enough for you and you have any questions.

          1 Reply Last reply
          0
          • E Offline
            E Offline
            ekkescorner
            Qt Champions 2016
            wrote on 10 Apr 2019, 12:00 last edited by
            #5

            @CristianoNarcisiVidex perhaps my blog gives you some hints: https://appbus.wordpress.com/2016/05/27/stacked-pages-app/ (it's something outdated, but you should get the idea HowTo deal with StackView)

            ekke ... Qt Champion 2016 | 2024 ... mobile business apps
            5.15 --> 6.8 https://t1p.de/ekkeChecklist
            QMake --> CMake https://t1p.de/ekkeCMakeMobileApps

            1 Reply Last reply
            2
            • C Offline
              C Offline
              CristianoNarcisiVidex
              wrote on 11 Apr 2019, 07:04 last edited by
              #6

              Thanks @ekkescorner !!! Your blog seems to be very interesting for my purposes. Anyway, i will try to answer either to @shaan7 . I would like to have something that doesn't need to know how the pattern is made. Let me try to explain better ( sorry but my english isn't so rich!).
              Each "page" must contain a Loader object for loading another source. In this way, going back and forward becomes only a call to Loader.setsource("next_page.qml"). The only problem is that i am not still able to close the "current" page as it loads a new one. Doing this, i will have only one QML file loaded at time, reducing the resources used by my interface. I have done this long time ago using QWidget, and i would like to do the same using QML .

              Any hint will be really appreciate!!!

              Thanks a lot

              1 Reply Last reply
              0
              • S Offline
                S Offline
                shaan7
                wrote on 11 Apr 2019, 07:14 last edited by
                #7

                Ah, so you don't want StackView-based navigation per se. In that case, lets say you first call Loader.setSource("Page1.qml"), the Loader will load it and display it. Now, when you want to load Page2, I understand that you want to unload Page1 to conserve resources. To do that, you can simply call Loader.setSource("Page2.qml") and it will do exactly that - it will unload Page1 and load Page2.

                1 Reply Last reply
                1
                • G Offline
                  G Offline
                  GrecKo
                  Qt Champions 2018
                  wrote on 11 Apr 2019, 09:52 last edited by
                  #8

                  Why not just use StackView and call replace when you want to change the page ?

                  1 Reply Last reply
                  1
                  • C Offline
                    C Offline
                    CristianoNarcisiVidex
                    wrote on 11 Apr 2019, 10:18 last edited by
                    #9

                    Ok @shaan7 !!! You are suggesting me to use one single Loader, and then each QML file that will be loaded must call it for changing the content of the page, right?
                    In this way i can't separate the the pages from the Loader, and i would like to separate each page from any other component as much as possible.

                    S 1 Reply Last reply 11 Apr 2019, 17:10
                    0
                    • C CristianoNarcisiVidex
                      11 Apr 2019, 10:18

                      Ok @shaan7 !!! You are suggesting me to use one single Loader, and then each QML file that will be loaded must call it for changing the content of the page, right?
                      In this way i can't separate the the pages from the Loader, and i would like to separate each page from any other component as much as possible.

                      S Offline
                      S Offline
                      shaan7
                      wrote on 11 Apr 2019, 17:10 last edited by
                      #10

                      @CristianoNarcisiVidex said in Dynamic QML Page loader:

                      In this way i can't separate the the pages from the Loader

                      Um, I'm not sure I understand what kind of separation you want here. No matter how you implement things, if you need some code in Page1 to navigate to Page2, then that code will have to call somefunc("Page2.qml"). When you're using a global Loader, its just that somefunc sets the Loader's active property accordingly.

                      As an example, lets say I call my somefunc as navigate:

                      main.qml:

                      Window {
                          width: 800
                          height: 600
                      
                          function navigate(page) {
                              loader.source =  page + ".qml";
                          }
                      
                          Loader {
                              id: loader
                              anchors.fill: parent
                              source: "Page1.qml"
                          }
                      }
                      

                      Page1.qml

                      Item {
                          id: page1
                      
                          Button {
                              text: "Next"
                              onClicked: navigate("Page2")
                          }
                      }
                      

                      Page2.qml
                      ... as required ...

                      In a different approach, I can use a StackView instead of Loader where the navigate will call replace as @GrecKo described.

                      C 1 Reply Last reply 12 Apr 2019, 08:44
                      2
                      • S shaan7
                        11 Apr 2019, 17:10

                        @CristianoNarcisiVidex said in Dynamic QML Page loader:

                        In this way i can't separate the the pages from the Loader

                        Um, I'm not sure I understand what kind of separation you want here. No matter how you implement things, if you need some code in Page1 to navigate to Page2, then that code will have to call somefunc("Page2.qml"). When you're using a global Loader, its just that somefunc sets the Loader's active property accordingly.

                        As an example, lets say I call my somefunc as navigate:

                        main.qml:

                        Window {
                            width: 800
                            height: 600
                        
                            function navigate(page) {
                                loader.source =  page + ".qml";
                            }
                        
                            Loader {
                                id: loader
                                anchors.fill: parent
                                source: "Page1.qml"
                            }
                        }
                        

                        Page1.qml

                        Item {
                            id: page1
                        
                            Button {
                                text: "Next"
                                onClicked: navigate("Page2")
                            }
                        }
                        

                        Page2.qml
                        ... as required ...

                        In a different approach, I can use a StackView instead of Loader where the navigate will call replace as @GrecKo described.

                        C Offline
                        C Offline
                        CristianoNarcisiVidex
                        wrote on 12 Apr 2019, 08:44 last edited by
                        #11

                        Thanks a lot @shaan7! We are about to reach a good solution. I am trying to do the same, but i would like to use Window instead of Item in QML pages. Changing this , the application gets closed after calling the setSource methods.
                        Is it the same to you?

                        Thanks!

                        S 1 Reply Last reply 12 Apr 2019, 13:07
                        0
                        • C CristianoNarcisiVidex
                          12 Apr 2019, 08:44

                          Thanks a lot @shaan7! We are about to reach a good solution. I am trying to do the same, but i would like to use Window instead of Item in QML pages. Changing this , the application gets closed after calling the setSource methods.
                          Is it the same to you?

                          Thanks!

                          S Offline
                          S Offline
                          shaan7
                          wrote on 12 Apr 2019, 13:07 last edited by
                          #12

                          @CristianoNarcisiVidex said in Dynamic QML Page loader:

                          but i would like to use Window instead of Item in QML pages

                          Why would you do that? It will mean that every time user navigates to new page, a new Window will be shown, it might not be a good experience.

                          About why the application gets closed, can you share a code snippet? Or even a link to a git repo works.

                          1 Reply Last reply
                          0
                          • C Offline
                            C Offline
                            CristianoNarcisiVidex
                            wrote on 12 Apr 2019, 14:54 last edited by CristianoNarcisiVidex 4 Dec 2019, 14:56
                            #13

                            here is the main.qml, where i have the loader

                            Window {
                                width: 640
                                height: 480
                            
                                function navigate(page)
                                {
                                    loader.setSource(page);
                                }
                                Loader
                                {
                                    id: loader
                                    anchors.fill: parent
                                    source: "FirstItem.qml"
                                }
                            }
                            

                            This is FirstItem.qml

                            Window{
                                visible: true
                                width: 800
                                height: 900
                                color: "green"
                            
                                Text {
                                    id: element
                                    x: 206
                                    y: 234
                                    text: qsTr("First Element")
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    font.bold: true
                                    anchors.horizontalCenter: parent.horizontalCenter
                                    anchors.verticalCenter: parent.verticalCenter
                                    font.pixelSize: 43
                                }
                            
                                MouseArea
                                {
                                    anchors.fill: parent
                                    onClicked:
                                    {
                            
                                        navigate("SecondItem.qml")
                            
                                    }
                                }
                            
                            }
                            
                            
                            

                            And this the second

                            Window{
                                visible: true
                                width: 640
                                height: 480
                                color: "white"
                            
                            
                                Text {
                                    id: element
                                    x: 206
                                    y: 234
                                    text: qsTr("Second Element")
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    font.bold: true
                                    anchors.horizontalCenter: parent.horizontalCenter
                                    anchors.verticalCenter: parent.verticalCenter
                                    font.pixelSize: 43
                                }
                            
                                MouseArea
                                {
                                    anchors.fill: parent
                                    onClicked:
                                    {
                            
                                        navigate("FirstItem.qml")
                            
                            
                                    }
                                }
                            
                            }
                            
                            1 Reply Last reply
                            0
                            • S Offline
                              S Offline
                              shaan7
                              wrote on 12 Apr 2019, 17:07 last edited by
                              #14

                              Ah ok, the app exits because the moment your first Window closes (before loading the second), your app has no visible Windows. By default, Qt apps will exit when that happens. You can disable this behavior by adding app.setQuitOnLastWindowClosed(false); in main.cpp

                              C 1 Reply Last reply 15 Apr 2019, 06:57
                              2
                              • S shaan7
                                12 Apr 2019, 17:07

                                Ah ok, the app exits because the moment your first Window closes (before loading the second), your app has no visible Windows. By default, Qt apps will exit when that happens. You can disable this behavior by adding app.setQuitOnLastWindowClosed(false); in main.cpp

                                C Offline
                                C Offline
                                CristianoNarcisiVidex
                                wrote on 15 Apr 2019, 06:57 last edited by
                                #15

                                @shaan7 said in Dynamic QML Page loader:

                                Wonderful!!! You deserve more than one like!!! Thank's a lot @shaan7 !!!

                                1 Reply Last reply
                                1

                                10/15

                                11 Apr 2019, 17:10

                                • Login

                                • Login or register to search.
                                10 out of 15
                                • First post
                                  10/15
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved