0

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.

user3453753
  • 357
  • 4
  • 15
  • 1
    When the application starts `hal1` is already on the stack. When you press `First` you are trying to replace `hal1` with `hal1` that does not make sense. – folibis Feb 10 '17 at 09:35
  • @folibis, thanks for pointing that out. I've fixed that, and the behaivor is still same. I see really weird inconsistency behaivor here. Anyways I've submit bugreport regarding this case here https://bugreports.qt.io/browse/QTBUG-58765 – user3453753 Feb 10 '17 at 11:13
  • As for me I don't see much point in using replace for `StackView` since right logic for stacked container is push-pop. May be you need `SwipeView` or something like this. – folibis Feb 10 '17 at 11:30
  • I've written many qml stuff using replace function, according to some docs , replace here means simply a "shortcut" of pop and then push the item. And I really like this :) . I want to minimize memory consumption by loading necessary page, and StackView is my proper lethal toolbox :) – user3453753 Feb 10 '17 at 11:50
  • If it works on some builds, it is not testable for us. So please describe what happens, when it does not work as expected? And maybe see, what are the differences in your setups? Do you have some files in either build-directory, that might cause this difference in behavior? – derM - not here for BOT dreams Feb 10 '17 at 13:30
  • 1
    As @folibis pointet out, the use of a `StackView` seems odd, as it does not seems like you stack anything. The mentioned `SwipeView` also tries to keep memory consumption low, by only loading up to three pages, to enable smooth transitions. Not so with your `StackView` - the objects are created at the beginning, kept alive for ever, and only the parenthood is controlled by the `StackView` – derM - not here for BOT dreams Feb 10 '17 at 13:38
  • You could download attached zip source sample project on here bugreports.qt.io/browse/QTBUG-58765 and try comparing between debug and release build. – user3453753 Feb 10 '17 at 14:39

1 Answers1

1

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.

  • Since we are talking about 2 Objects only at this time, yes: The Memory-Consumption is the same, as the `SwipeView` holds up to three Objects in the memory. However the `SwipeView`'s `default property` seems to be a `default property Component`, that wrapps everything in a `Component` even if you have not done it. This means: `SwipeView { ... Component { Item {} } ... }` results in the same thing as `SwipeView { ... Item {} ...}`. In both cases, the `Item` is only created when needed (shown, or next to the shown one) – derM - not here for BOT dreams Feb 10 '17 at 14:24
  • I've updated my question to make clearer. Does that make more sense to you? – user3453753 Feb 10 '17 at 15:16