declare global property in QML for other QML files

前端 未结 6 514
孤街浪徒
孤街浪徒 2020-11-27 17:53

I want to declare a global property in a config file and use it in other files. for example declare mainbg in:

Style.qml:



        
相关标签:
6条回答
  • 2020-11-27 17:55

    Use a QML Singleton.

    Please reference "Approach 2" on this page -- The ugly QTBUG-34418 comments are mine.

    These are the pieces you need:

    Style.qml

    pragma Singleton
    import QtQuick 2.0
    QtObject {
        property color mainbg: 'red'
    }
    

    qmldir

    This file must be in the same folder as the singleton .qml file (Style.qml in our example) or you must give a relative path to it. qmldir may also need to be included by the .qrc resource file. More information about qmldir files can be found here.

    # qmldir
    singleton Style Style.qml
    

    How to Reference

    import QtQuick 2.0
    import "."  // this is needed when referencing singleton object from same folder
    Rectangle {
        color: Style.mainbg  // <- there it is!!!
        width: 240; height 160
    }
    

    This approach is available since Qt5.0. You need a folder import statement even if referencing the QML singleton in the same folder. If is the same folder, use: import "." This is the bug that I documented on the qt-project page (see QTBUG-34418, singletons require explicit import to load qmldir file).

    0 讨论(0)
  • 2020-11-27 17:55

    Adding some contribute to @pixelgrease answer, I found another technique that doesn't require the path relative import ".", workarounding the bug QTBUG-34418. This is useful especially if one has qmldir and singleton class in a different place than the qml file where the singleton is used. The technique requires defining a proper module inside the tree structure: the module is then resolved by adding the parent path of the module to the QML engine with QmlEngine::addImportPath(moduleParentPath). For example:

    qml/
    ├── <ModuleName>/
    │ ├── <ClassName>.qml
    │ ├── qmldir
    

    In main.cpp you have then:

    QQmlApplicationEngine engine;
    engine.addImportPath("qrc:/qml");    // Can be any directory
    engine.load("qrc:/qml/main.qml");
    

    If you use resources, qml.qrc:

    <RCC>
     <qresource prefix="/">
          (...)
     <file>qml/main.qml</file>
     <file>qml/MySingletons/MySingleton.qml</file>
     <file>qml/MySingletons/qmldir</file>
     </qresource>
    </RCC>
    

    In qmldir:

    module MySingletons
    singleton MySingleton 1.0 MySingleton.qml
    

    In main.qml, or any other qml file in a different directory:

    import MySingletons 1.0
    

    Then you use MySingleton class as usual. I attached the example MySingletonWithModule.7z to bug QTBUG-34418 for reference.

    0 讨论(0)
  • 2020-11-27 18:14

    Basically, if you don't need property binding (if you value is a constant and will not need to be notifiable on change) you can define it in a Javascript shared library, like this :

    // MyConstants.js
    .pragma library
    var mainbg = "red";
    

    And use it in QML like this :

    import "MyConstants.js" as Constants
    
    Rectangle {
         color: Constants.mainbg;
    }
    

    But the bad side of this are : - no strong typing (JS doesn't really know about types) so you could put anything even if it is not a color. - and if you change mainbg, the Item using it won't be notified about the change and will keep the old value

    So if you need type checking and binding/change notify, simply declare your property as a member of the root object in you main.qml, and it will be accessible from everywhere in the QML application, because the property will in fact be directly registered into the Qml Context object, which is global by definition.

    Hope it helps.

    0 讨论(0)
  • 2020-11-27 18:17

    You can always create a new QML object file that contains the properties that you want shared across qml files. Just import it the same way you would any QML object and you have access to properties. Now, if you want to be able to modify these properties and have the changes shared across instances things get a lot trickier and you will most likely want to resort to some sort of solution using the .pragma library js files. Unless you want to write some sort of C++ alternative.

    0 讨论(0)
  • 2020-11-27 18:18

    You can create a js file and import it to all of the files that have to use this property.

    js file:

    //Note: you only need '.pragma library' if you are planning to
    //change this variable from multiple qml files
    .pragma library
    var globalVariable = 20;
    

    qml file:

    import "test.js" as Global
    
    Rectangle {
      id: main
      width: 300; height: 400
    
      Component.onCompleted: {
        console.log( Global.globalVariable)
        //you can also change it
        Global.globalVariable = 5
      }
    }
    
    0 讨论(0)
  • Add this property in main and you can access it in any qml,this may not be the correct way but this works.

    or if you want to group the property add them in a qml include that qml in main and give an id,now you can access this property using that id

    main.qml

     Item{
     width:10
     height:10
    
     Model{
     id:globdldata
     }
    
    
    
     }
    

    Model.qml

    Item {
    
    property color mainbg: 'red'
    
    }
    

    you can use globdldata.mainbg anywhere

    0 讨论(0)
提交回复
热议问题