How to access an ID across QML files
-
I'm not sure if QML1 and QML2 is a valid component name, but assuming it was you might end up with some code in another file along the lines of
Item { QML1 { id: rect1 } QML2 { text: rect1.title } }
at least that's how I generally seem to end up structuring things when I find I need to "wire up" elements and properties in different files.
If things are more dynamic, I've also used the objectName property (a string) to give elements unique names, and then iterated over the children of the containing element looking for a specific objectName. Not an approach I'd want to get into the habit of using though: wary of the performance impact if overused, and I generally take it to be a "bad code smell" that I should probably be doing something else more clever.
-
@pra7 Listen to @timday. The problem in your two files is that a qml file is a component and you can't use components, or types, without first creating objects of those types. You didn't give the whole files; you may already have something like
ColumnLayout { QML1 { } Text { text:rect1.title //**ERROR** ReferenceError: rect1 is not defined } }
in your QML2. In that case the problem is that you can't use the id used inside a component file outside that file. You have to give it an id when you create the object, for example:
QML1 { id: rect1 } Text { text:rect1.title //no error
The id there can be the same as inside the component file but it can be something else, it doesn't matter.
-
@pra7 You haven't given us enough information to solve this problem. When you write your component files they either are independent - they don't use each other - or one uses another. The former case is in timday's example, the latter in mine. Logically there are no other possibilities and one of these will solve your problem in one way or another.
Maybe your real problem is that you don't understand well how ids are used and what they are. You have to understand scope. Have you already read and understood the basic QML documentation about "Scope and Naming Resolution" and "QML Documents", and "The id Attribute" in "QML Object Attributes"?
You probably don't need a singleton, you just have to create one object and use it. That's what timday's minimal example does. But you may have to do it in a more complicated way. Again, you didn't give us enough information.
-
@Eeli-K I agree that there is not enough information and I read about how "Scope and Naming Resolution" and "QML Documents", and "The id Attribute" in "QML Object Attributes", I just wanted to know that is there any other possibilities so that I will become simpler to implement.
As I am still in design phase I am not having much information to share, just looking around the possibilities to implement.
My question is if QML1 is singleton object then can I use anywhere without initializing it ? in my case say if "QML1 " is singleton, later without initializing QML1, can I use the QML1 object in QML2 just by importing?
-
@pra7 You can't use a QML type as a singleton like that. If you've got a component in file QML1.qml there just doesn't exist an accessible object of that type before you write QML1 {} somewhere (and before it's evaluated). If you want a singleton object to be used in all your QML files you can make a C++ singleton and register it appropriately. But its usefulness compared to a normal object is limited. So, what do you mean by "singleton" here and why do you need that instead of just an object?
-
@pra7 OK, now I understand better. I haven't used that. But notice that in the example the singleton is used only to carry values and is a QtObject - you were trying to use a Rectangle which is a visual type. Second, you were trying to use id while in the example the singleton doesn't have an id but is referred to by its type name Style (note that property names and id names must begin with a lowercase letter, type names and therefore component file names must begin with uppercase letter). Notice also "pragma Singleton" and "import "."". If it still doesn't work you have to give the complete contents of both or all files here - we already saw how incomplete information leads to long fruitless discussions and speculations.
-
This got me thinking about how I structure things, which generally results from starting with a small one-file prototype and then breaking bits of it off into different files. Here's an example (all these can be run with qmlscene main.qml):
First you might have
File main.qml
// main.qml import QtQuick 2.7 Rectangle { id: main width: 640 height: 480 property string msg0: "Some text" property string msg1: "Some more text" Column { anchors.centerIn: parent Text {text: main.msg0} Text {text: main.msg1} } }
then you might try and organize stuff a bit:
import QtQuick 2.7 Rectangle { id: main width: 640 height: 480 Item { id: config property string msg0: "Some text" property string msg1: "Some more text" } Column { anchors.centerIn: parent Text {text: config.msg0} Text {text: config.msg1} } }
then you might split that up with a Config.qml:
import QtQuick 2.7 Item { property string msg0: "Some text" property string msg1: "Some more text" }
and main.qml now simplified to:
import QtQuick 2.7 Rectangle { id: main width: 640 height: 480 Config {id: config} Column { anchors.centerIn: parent Text {text: config.msg0} Text {text: config.msg1} } }
and then you start moving out other bits of functionality e.g adding a Messages.qml:
import QtQuick 2.7 Column { anchors.centerIn: parent Text {text: config.msg0} Text {text: config.msg1} }
and main.qml now simplified to:
import QtQuick 2.7 Rectangle { id: main width: 640 height: 480 Config {id: config} Messages {} }
I've never felt any need for singletons in QML code at all. (Having the hosting C++ set some context properties based on environment or command-line-options is the probably the closest I've come).