在QML中为其他QML文件声明全局属性

时间:2013-03-06 21:00:49

标签: qt variables scope qml global-variables

我想在配置文件中声明一个全局属性,并在其他文件中使用它。例如,在<:p>中声明mainbg

Style.qml

property color mainbg: 'red'

并在其他QML文件中使用它(例如view.qmlmain.qml)。我该怎么做才能做到这一点?

6 个答案:

答案 0 :(得分:35)

使用QML Singleton。

请参阅this page上的“方法2” - 丑陋的QTBUG-34418评论是我的。

这些是您需要的部分:

Style.qml

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

qmldir

此文件必须与单例.qml文件(在我们的示例中为Style.qml)位于同一文件夹中,或者您必须提供相对路径。 .qrc资源文件可能还需要包含qmldir。有关qmldir文件的更多信息,请访问here

# qmldir
singleton Style Style.qml

如何参考

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
}

从Qt5.0开始,这种方法可用。即使在同一文件夹中引用QML单例,您也需要文件夹import语句。如果是同一个文件夹,请使用:import "."这是我在qt-project页面上记录的错误(参见QTBUG-34418,单例需要显式导入才能加载qmldir文件)。

答案 1 :(得分:23)

基本上,如果您不需要属性绑定(如果您的值是常量而不需要在更改时通知),您可以在Javascript共享库中定义它,如下所示:

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

并在QML中使用它:

import "MyConstants.js" as Constants

Rectangle {
     color: Constants.mainbg;
}

但不好的一面是: - 没有强烈的打字(JS并不真正了解类型),所以你可以放任何东西,即使它不是一种颜色。 - 如果您更改mainbg,则使用该项目的项目将不会收到有关更改的通知,并将保留旧值

因此,如果您需要进行类型检查和绑定/更改通知,只需将您的属性声明为main.qml中根对象的成员,并且可以从QML应用程序中的任何位置访问它,因为该属性实际上是直接注册到Qml Context对象中,根据定义是全局的。

希望它有所帮助。

答案 2 :(得分:19)

您可以创建一个js文件并将其导入所有必须使用此属性的文件。

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文件:

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
  }
}

答案 3 :(得分:5)

添加一些有助于@pixelgrease的答案,我找到了另一种不需要路径相对import "."的技术,解决了错误QTBUG-34418。如果一个人在与使用单例的qml文件不同的地方有qmldir和singleton类,这将非常有用。该技术需要在树结构中定义适当的模块:然后通过将模块的父路径添加到具有QmlEngine::addImportPath(moduleParentPath)的QML引擎来解析模块。例如:

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

在main.cpp中你有:

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

如果你使用资源,qml.qrc:

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

在qmldir:

module MySingletons
singleton MySingleton 1.0 MySingleton.qml

在main.qml或其他目录中的任何其他qml文件中:

import MySingletons 1.0

然后像往常一样使用MySingleton类。我将示例MySingletonWithModule.7z附加到bug QTBUG-34418以供参考。

答案 4 :(得分:2)

在main中添加此属性,您可以在任何qml中访问它,这可能不是正确的方法,但这可行。

或者如果要对属性进行分组,请将它们添加到qml中 在main中包含该qml并给出一个id,现在您可以使用该id

访问该属性

main.qml

 Item{
 width:10
 height:10

 Model{
 id:globdldata
 }



 }

Model.qml

Item {

property color mainbg: 'red'

}

你可以在任何地方使用globdldata.mainbg

答案 5 :(得分:1)

您始终可以创建一个新的QML目标文件,其中包含您希望在qml文件中共享的属性。只需像导入任何QML对象一样导入它,即可访问属性。现在,如果您希望能够修改这些属性并在各实例之间共享更改,那么事情会变得更加棘手,您很可能希望使用.pragma库js文件来使用某种解决方案。除非你想编写某种C ++替代方案。