Keep the state of the view in a StackView
-
Hello,
I have a StackView in my App in order to make navigation between different pages.
It is the first time I use StackView and I'm not sure to understand the complete behaviour.
Here is a sample of my code/The StackView element :
StackView { id: stack anchors.fill: parent initialItem: 'file:qml/menu.qml' }
The function I use to show a page :
function loadPage(page){ switch(page){ case 0 : launchPage('menu') break case 1 : launchPage('page1') break case 2: launchPage('page2') break case 3: launchPage('page3') break } } function launchPage(page){ return stack.push('file:qml/'+page+'.qml'); }
It behaves quite good except from one detail. When I press a button on my menu it opens the right page. I can use the components of the page but once I go back to menu and come back to my page I've lost my actions on the components.
For example if my page1 has a Textinput : When I go on page1 and change the value of the TextInput then go to menu and come back to page1 my TextInput has been reset.
I thought it would be reset only if I pop() my page but obviously not.
What should I do to keep my changes on the page ?
Maybe each time I press the menu button it open a new instance of page1 ? -
hi @DavidM29 ,
As far as I know, that is indeed what happens here.
with
return stack.push('file:qml/'+page+'.qml');
you tell the stackview to create a new Item from that qml file and show it.I believe if you have the components as actual items/instances in your main qml, than it should work like you thought it would.
something like this (taken from the docs):
StackView { id: stack initialItem: view Component { id: view MouseArea { Text { text: stack.depth anchors.centerIn: parent } onClicked: stack.push(view) } } }
-
@DavidM29 said in Keep the state of the view in a StackView:
For example if my page1 has a Textinput : When I go on page1 and change the value of the TextInput then go to menu and come back to page1 my TextInput has been reset.
Thats also i would expect, but u didn't show how you "go back" again.
Is it correct that a page can launch a menu? If so everytime a new menu page is pushed into the stack view? is that correct?
-
I go back on the menu by calling launchPage(0) on press of a button, which call a dedicated .qml file (a window with a few buttons).
So from what you told me when I "push()" a page it load a new instance of this one. Wich is not what I want to do. How Am I supposed to handle this ?
I'm obliged to create an instance of each page but don't wan't more. I just want to switch from one to another. Just like setCurrentIndex(x) behave in a QStackWidget in a standart Qt UI. -
@DavidM29
the QML stackview behaves a bit different here than the C++ stackkview.Why not simply create all 4 pages, anchor them to the same parent. and bind their visibility to a page property:
visible: page === someItem.currentPage
. Then simply switch pages by assigning the page index tosomeItem.currentPage
Alternatively you could also create a ListView element with a ObjectModel:
ListView { id: list snapMode: ListView.SnapOneItem currentIndex: ... // the page to show interactive: false ObjectModel { Item { height: list.height; width: list.width } Item { height: list.height; width: list.width } Item { height: list.height; width: list.width } } }
adapt some more properties of the ListView like disabling scrolling etc
-
@raven-worx
Finally I used your first solution here is a sample of the code I used :main.qml
Menu{ id:p0 visible: true } Page1{ id: p1 visible: false } Page2{ id: p2 visible: false } } function loadPage(page){ resetPages() switch(page){ case 0 : p0.visible=true break case 1 : p1.visible=true break case 2: p2.visible=true break } } function resetPages(){ p0.visible=false p1.visible=false p2.visible=false }
This works fine. If you see any improvements I can make please tell me.