Search code examples
javascriptqtqmlqtquick2qt5.6

QML StackView replace nothing to push


how to correctly switch between pages according following samples:

import QtQuick 2.6
import QtQuick.Layouts 1.0
import Qt.labs.controls 1.0

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

StackView {
    id: stack
    anchors.fill: parent
    initialItem: hal1
}

Pane {
    id: hal1
    anchors.fill: parent
    background: Rectangle {
        id: mystart
        anchors.centerIn: parent
        color: "#2196F3"
    }
}

Pane {
    id: hal2
    anchors.fill: parent
    Label {
        text: qsTr("Second page")
        anchors.centerIn: parent
    }
}

footer: TabBar {
    id: tabBar
    currentIndex: 0
    TabButton {
        text: qsTr("First")
        onClicked: {
           if(stack.currentItem==hal1){
                console.log("dont switch hal1 !")
                return
          }
          stack.replace(hal1)
        }
    }
    TabButton {
        text: qsTr("Second")
        onClicked: {
            if(stack.currentItem==hal2){
                console.log("dont switch hal2 !!")
                return
            }
            stack.replace(hal2)
        }
    }
  }
}

Whenever clicking the first tab I want to get the rectangle and the second tab I want to get my simple label. I'm using qt labs controls 5.6 thanks

EDIT: Look like this code only works for debug build not for release build. Tested on msvc2015 windows. I do not know exactly why this happen, any pointers?

Ok I attached another sample project here to make this case clearer. There are two problems here the first thing is I get warning message "StackView replace nothing to push" and inconsistency behaivor between debug and release build. The debug build is working fine and I get unexpected result at release build.


Solution

  • Though your issues are unclear to me, I try with an answer as the comments are too limited, to adress the many issues with your code.

    First for your edit:

    EDIT: Look like this code only works for debug build not for release build. Tested on msvc2015 windows. I do not know exactly why this happen, any pointers?

    So there needs to be some substantial difference between your two build-setups. Check for the differences, especially in the build-directories. Any lingering files, that should not be there from older builds maybe? Is everything properly compiled?

    Then to your layering:

    • Your first layer is the StackView
    • Ontop you have hal1
    • Above you have hal2

    Then you have the initialItem set, which reparents hal1 to the StackView hal2 remains on top, until you have it once displayed in the StackView, therefore you should see hal2 initally.

    Then to your misconception regarding the memory consumption:
    The StackView does not minimize memory consumption. When you push something on the StackView it is only reparented to it, and set visible. When popping it off, it is reparented to the original parent, and turned invisible. To verify my claims log the Component.onCompleted and Component.onDestruction. The first happens on startup, the latter on shutdown of the application, not when the page gets pushed or popped. Therefore the memory consumption is constantly high. The only way to prevent this, is to have them created dynamically.
    Edit As BaCaRoZzo pointed out, to keep the memory low when using the StackView this is important. It can be done, e.g. by passing a Component rather than a statically created Item. In this case, the StackView takes care of the creation, and the object is destroyed once it is popped of the stack.

    The SwipeView, mentioned by folibis makes things a little bit easier. As its default property is of type Component, so everything you write SwipeView { ... here ...} is not immediately instantiated, but stored as Component to be instantiated only when needed. This is, when it is shown, or likely to be shown soon (left or right of the currentItem). So we can see, from the view of memory consumption both ...Views can be used efficiently. The usage comes with different flavor though, and the semantics of a SwipeView and a StackView differ. Usually the SwipeView seems more natural, when having multiple pages in parallel while the StackView is the way to go, when you do exactely what it's name suggests: stack Items

    When talking about the way to go: Why do you go with Qt.labs.controls rather than the QtQuick.Controls 2.0? In contrast to the labs-version they tend to be more stable, and the behavior should be less likely to change for other releases.

    Now, I hope I helped you with something, even though I might have failed to address your problem, as you have not stated it in your question yet.