1
votes

I would like to implement key handlers for different pages of a StackView. The problem with StackView is that it uses "item" attribute to display a qml page. Therefore, what's declared inside a StackView page (e.g. HomePage.qml), since it is not instantiated explicitly, is not visible to main.qml.

In order to overcome this problem, I am trying to declare a signal at window and place its callback in StackView page (it's dumb, but please suggest what else to do). Here is how it roughly looks:

main.qml
-----------
Window {
    id: window

    signal keyReceived();
    property var key;

    StackView {
        id:stackView
        initialItem: "HomePage.qml"
    }
}

HomePage.qml
-------------
Page {
    id: homePage
    window.onKeyReceived:{
         // Here "window" is not recognized, since this type of use does not exist?
    }
}

All in all, I want to be able to declare a global variable that is visible in both main.qml and HomePage.qml, and be able to notified by the changes to that variable. Be it with signals or other things, does not matter. Any help is greatly appreciated.

1

1 Answers

1
votes

Here you go:

Page {
    id: homePage
    Connections {
        target: window
        onKeyReceived: {
        }
    }
}

The reason this will work is it uses QML context chaining at runtime through the StackView up to the Window to resolve the window id reference.

The reason your first approach doesn't work is that references to signal handlers above the current type aren't statically resolvable. I.e. QML doesn't know who is going to be the parent of Page at runtime so it can't resolve the type of window and thus can't resolve the type and arguments of the signal keyReceived. Those kinds of references only work for the current type and all children statically defined below it.

So, whenever you need to connect to a type that QML can't figure out the static definition for (like a reference up the context chain) you must use a Connections object which will figure all of that out at runtime.