Annyo
Annyo

Reputation: 1477

How to access containing QML StackView?

I am new to QML, I have a Component which is pushed on a StackView. I'd like from this component to access the StackView containing it.

Here is a code that works

import QtQuick 2.11
import QtQuick.Controls.2.2

ApplicationWindow {
    id: window

    StackView {
        id: stackView
        initialItem: test1
        anchors.fill: parent
    }
    Component {
        id: test1
        Button {
            text: "Go to test2"
            onClicked: stackView.push(test2)
        }
    }
    Component {
        id: test2
        Button {
            text: "Back to test1"
            onClicked: stackView.pop()
        }
    }
}

However, I'd like to avoid accessing stackView by its id

Stack.view seems to be what I'm looking for, but I have no idea how to use it. I tried all of the following (replacing Buttons' onClicked) :

Stack.view.push(test2)
view.push(test2)
test1.Stack.view.push(test2)
test1.view.push(test2)

None of these work. Am I misunderstanding something ? How am I supposed to use Stack.view ?

Edit : this question looks really close to mine : Access QML StackView from a control

I could indeed use a property to keep a reference to my StackView, but I would still like to avoid that if possible. The accepted answer says that root.StackView.view.pop() is the correct method. I assume root is the Page's id from this post, so I tried test1.StackView.view.push(test2), but this still doesn't work. (Also tried with root, but it's not better)

Upvotes: 1

Views: 3519

Answers (2)

Stephen Quan
Stephen Quan

Reputation: 25871

A simple way of convenient using StackView.view is by assigning it to a property. In the following, I deliberately did not give the parent StackView an id. I can create a property in the sub-pages to grant access to the StackView as follows:

    property StackView stackView: StackView.view

Here's a fully working example:

import QtQuick 
import QtQuick.Controls

Page {
    StackView {
        anchors.fill: parent
        initialItem: "Test1.qml"
    }
}

//Test1.qml
import QtQuick 
import QtQuick.Controls

Page {
    property StackView stackView: StackView.view
    Button {
        anchors.centerIn: parent
        text: "Go to test2"
        onClicked: stackView.push("Test2.qml")
    }
}

//Test2.qml
import QtQuick 
import QtQuick.Controls

Page {
    property StackView stackView: StackView.view
    Button {
        anchors.centerIn: parent
        text: "Back to test1"
        onClicked: stackView.pop()
    }
}

You can Try it Online!

Upvotes: 1

derM
derM

Reputation: 13691

Be aware that this Q/A is about the QtQuick.Controls 2.x

I also think it is good style to first use the attached property, rather than doubling this functionality by adding own, custom properties.

The problem is, that you are using the attached property in the wrong place - it is attached to the Item that is pushed onto the StackView and not to any of its children. So to use the attached property, you need to specify an identifier of this Item first.

In the example, that has been linked, this is root. But it is not the id of the Component-object. It has to be the root-node of the content of the Component-object.

You should have something like this:

Component {
    id: myComponent
    Item { // The Page. To this the attached property will be attached.
        id: myComponentRoot // Use this to identify the root node of the pushed item.
        Item { // Some more layers ...
        ...
            Button { // Here you now want to access it perhaps?
                onClicked: myComponentRoot.StackView.view.pop() // Reference the root node of the component to access it's attached properties.
            }
        }
    }
}

Upvotes: 1

Related Questions