Accessing id of object in a separate qml file
-
Hello everyone,
I have a question regarding the access of an id from another qml file.
I have a qml file called "Stackview.qml" with following code:
import QtQuick 6.2 import QtQuick.Controls 2.15 Item { anchors.fill: parent StackView{ id:stackview anchors.fill: parent initialItem: "itemone.qml" } }
and I want to push/pop a page via accessing the stackview in another qml file that looks like this:
//... MouseArea{ anchors.fill:parent onClicked: { model.currentIndex = index if(index===1){ stackview.push("itemone") } if(index==2){ stackview.push("itemtwo") //...
But I get an error that stackview is undefined. I have watched a youtube video to learn it, and went almost like he did ( stackviewyoutubevideo)
On timestamp 17:00 min the stackview qml is defined and on timestamp 22:30 min the id: stackview can be accessed on the separate qml file to use the push methode.
But when I do it, qt says stackview is undefined. Why could he use it and with me it doesn't work. He uses a Button "widget" that I can't see as a self defined qml file, so I guess it is something like a predefined widget. Could that give the access to the stackview?
Thank you in advance.
Best regards
-
@Luffy97 said in Accessing id of object in a separate qml file:
But I get an error that stackview is undefined.
It helps to post the complete, minimal working example, and the exact error message.
Let's start with a link to the source code, instead of a 30 minute video.
https://github.com/MontyTheSoftwareEngineer/StackView-Loader-DyamicObjectsA simplified version of the program is:
StackViewPage.qml:
import QtQuick.Controls StackView { id: stackview initialItem: "A.qml" }
A.qml:
import QtQuick.Controls Button { onClicked: stackview.push("A.qml") }
When the Button in A.qml is clicked, the QML engine attempts to resolve the
stackview
id. Lookup fails in the current file, so the engine checks the parent context, and then the grandparent context, and so on. Note that it does not check sibling or child contexts.Accessing an id not present in the current component definition is strongly discouraged.
If an item needs access to another item, pass it explicitly as a property.
Base.qml:
import QtQuick Row { Rectangle { id: rect; width: 25; height: 25; color: "red" } MyItem { target: rect } }
MyItem.qml:
import QtQuick import QtQuick.Controls Item { required property Rectangle target Button { onClicked: target.color = "green" } }
In this particular case, the attached property StackView.view can be used for access to the view. See the attached property documentation for details.
-
Thank you for the explanation. I now understand how the id is being searched by the engine and if it is not inside the familytree that it cannot simply find it.
I changed the structure of my files and code and now the id is visible.
I used the Loader like in the video to load my stackview in the loader. I have a drawermenu that is a complete separate file that when clicked on one of its menupoints tries to push the page files that should be stacked on top (also in separate qml files like in the video) to the stackview.
Like you said with the familytree,
the issue was what the drawermenu was not included in the loader, so there was no connection from my drawermenu.qml to the stackview.qml. The drawermenu was on top of the loader region and so separetly shown in the app. Once I included the complete screen, therefore the drawermenu as well, inside the loader, it now was able to get access to the id of the StackView in the stackview.qml from my drawermenu.qml.I don't know if it's root was the problem you explained with how the engine works or something else. But now I can access the id and use the push and pop methode.
Thank you for your time.
Best regards
-
-
@Luffy97 It sounds like this code is sticking with the use of an id outside of the file it is declared in. It's your code, but I strongly suggest not doing this. It creates code that is harder to understand or refactor, and easier to break.
Either pass the id of the StackView to drawermenu via a property, or have the menu emit a signal when an item is selected. Emitting a signal is generally the more flexible design.