34

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

样式.qml

property color mainbg: 'red'

并在其他 QML 文件(如view.qmlmain.qml)中使用它。我怎样才能完成这项工作?

4

6 回答 6

50

使用 QML 单例。

请参考本页上的“方法 2” ——丑陋的 QTBUG-34418评论是我的。

这些是您需要的部分:

样式.qml

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

qmldir

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

# 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 开始可用。import即使在同一文件夹中引用 QML 单例,您也需要一个文件夹语句。如果是同一个文件夹,请使用:import "."这是我在 qt-project 页面上记录的错误(请参阅 QTBUG-34418,单例需要显式导入才能加载 qmldir 文件)。

于 2014-08-04T16:59:20.377 回答
26

基本上,如果您不需要属性绑定(如果您的值是一个常量并且不需要在更改时通知),您可以在 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 对象中,根据定义,它是全局的。

希望能帮助到你。

于 2013-03-27T12:27:07.313 回答
21

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

.js 文件:

//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
  }
}
于 2013-03-07T07:42:17.903 回答
8

添加一些有助于@pixelgrease 答案,我发现了另一种不需要路径 relative 的技术import ".",解决了错误QTBUG-34418。这很有用,尤其是当一个qmldir单例类位于与使用单例的 qml 文件不同的位置时。该技术需要在树结构中定义一个适当的模块:然后通过将模块的父路径添加到 QML 引擎来解析模块,使用QmlEngine::addImportPath(moduleParentPath). 例如:

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

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

于 2017-06-17T11:51:02.050 回答
3

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

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

main.qml

 Item{
 width:10
 height:10

 Model{
 id:globdldata
 }



 }

模型.qml

Item {

property color mainbg: 'red'

}

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

于 2017-02-22T04:46:19.983 回答
1

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

于 2013-03-07T16:45:16.133 回答