How to access an ID across QML files



  • Hello, I am not getting how to access a ID from one QML to another QML.

    NOTE: QML files are located in different directory ,Below is the code:

    //QML1.qml

    Rectangle
    {
        property alias rect1:rect1
        property string title:"some text"
        id:rect1
    }
    

    //QML2.qml

    Text
    {
       text:rect1.title //**ERROR** ReferenceError: rect1 is not defined
    }


  • 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.



  • @Eeli-K Thanks for the example but I need to access QML1 without creating an object in QML2 and if I create a QML1 object in QML2 the object will be re created and I may not get the correct value. I think I should use singleTon.



  • @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?



  • @Eeli-K I am referring following link : http://wiki.qt.io/Qml_Styling#Approach_2:_Style_Singleton

    According to above link, I can use QML controls as SingleTon, Is my understanding correct ?



  • @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.



  • @Eeli-K I will try singleton and sorry, From now will post complete information. Thanks.



  • 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).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.