8

We need to develop a QtQuick project, where we have about 100 screens.

I had tried to make a demo project for the navigation which has three screens on button click. I had used the concepts of 'States' in the navigation between the pages. Initially I tried the same using 'Loader' but loader was not able to retain the previous state of page, it was re-loading the entire page during the navigation.

Below is the code snippet of main.qml

// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
import QtQuick 1.1

Rectangle {
    id:main_rectangle
    width: 360
    height: 640

    Page1{
        id:page1
    }

    Page2{
        id:page2
    }

    Page3{
        id:page3
    }

    states: [
        State {

            name: "page2"

            PropertyChanges { target: page3; visible:false; }
            PropertyChanges { target: page1; visible:false; }
            PropertyChanges { target: page2; visible:true; }
        },
        State {
            name: "page1"
            PropertyChanges { target: page3; visible:false; }
            PropertyChanges { target: page2; visible:false; }
            PropertyChanges { target: page1; visible:true; }
        },

        State {
            name: "page3"
            PropertyChanges { target: page1; visible:false; }
            PropertyChanges { target: page2; visible:false; }
            PropertyChanges { target: page3; visible:true; }
        }

    ]

}

This runs well with the small POC with three screens, but its not feasible to define states for 100 screens.

From designing aspect we concluded to make a C++ controller we controls the states, visibility of various pages.

Need suggestions how to implement the 'State' logic in C++.

DNamto
  • 1,342
  • 1
  • 21
  • 42

2 Answers2

7

Here is the simplest solution in plain QML, using a configurable page list (like a model) + a Repeater + Loader items to not load everything at startup (lazy instanciation) and not destroy a page after hiding it (to not have to reload it if we come back to it) :

import QtQuick 1.1

Rectangle {
    id: main_rectangle;
    width: 360;
    height: 640;

    // Put the name of the QML files containing your pages (without the '.qml')
    property variant pagesList  : [
        "Page1",
        "Page2",
        "Page3",
        "Page4",
        "Page5"
    ];

    // Set this property to another file name to change page
    property string  currentPage : "Page1";

    Repeater {
        model: pagesList;
        delegate: Loader {
            active: false;
            asynchronous: true;
            anchors.fill: parent;
            visible: (currentPage === modelData);
            source: "%1.qml".arg(modelData)
            onVisibleChanged:      { loadIfNotLoaded(); }
            Component.onCompleted: { loadIfNotLoaded(); }

            function loadIfNotLoaded () {
                // to load the file at first show
                if (visible && !active) {
                    active = true;
                }
            }
        }
    }
}

Hope it helps !

TheBootroo
  • 7,408
  • 2
  • 31
  • 43
  • 2
    To go further, you can replace the use of `visible` property with a custom one, let's say `shown` that will be used together with `scale` or `opacity` and some `Behavior {}` component to do nice page change transition... – TheBootroo Mar 27 '13 at 10:44
  • 1
    And if your page's QML files aren't in the same folder, you will need to provide the relative path before the page file name in the array and in the `currentPage` property : - if in a subfolder: "folderName/fileName" - if in a parent folder: "../folder/filename" - eventually an absolute path, but not a very good idea ! – TheBootroo Mar 27 '13 at 10:57
  • Bootroo's answer won't compile in Quick 2. Here are the changes: `main_rectangle.currentPage` and `main_rectangle.pagesList`, looks like variables now scope. Hope this helps someone. – jkj yuio Feb 11 '16 at 17:39
1

I suggest to use StackView from Qt Quick Components. Here is its documentation.

Pavel Osipov
  • 2,067
  • 1
  • 19
  • 27
  • What I know PageStack is specifically for Symbian platform. Will it work on desktop platform on Windows OS? – DNamto Oct 24 '12 at 14:06
  • If your navigation pattern looks like in the phone, I think it is possible to use it. In desktop Qt Quick components, which I downloaded now, I see only one "View Manager" - TabBar. – Pavel Osipov Oct 24 '12 at 14:13
  • I can say from experience that the PageStack can definetly be a solution here. However, it is not a very complicated control and you can always consider implementing your own. Basically you create a parent object that has an array as a page stack and you use the QML dynamic object creation to create pages and push them onto the stack as needed. I highly suggest looking into the code of the PageStack in the components. It is not very complicated at all, and my inspire you. – Deadron Mar 01 '13 at 19:18