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

2 8*_*2 8 24 variables qt scope global-variables qml

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

Style.qml:

property color mainbg: 'red'
Run Code Online (Sandbox Code Playgroud)

并在其他QML文件(如view.qmlmain.qml)中使用它.我该怎么做这个工作?

pix*_*ase 37

使用QML Singleton.

请参考本页的 "方法2" - 丑陋的QTBUG-34418评论是我的.

这些是您需要的部分:

Style.qml

pragma Singleton
import QtQuick 2.0
QtObject {
    property color mainbg: 'red'
}
Run Code Online (Sandbox Code Playgroud)

qmldir

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

# qmldir
singleton Style Style.qml
Run Code Online (Sandbox Code Playgroud)

如何参考

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
}
Run Code Online (Sandbox Code Playgroud)

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


The*_*roo 23

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

// MyConstants.js
.pragma library
var mainbg = "red";
Run Code Online (Sandbox Code Playgroud)

并在QML中使用它,如下所示:

import "MyConstants.js" as Constants

Rectangle {
     color: Constants.mainbg;
}
Run Code Online (Sandbox Code Playgroud)

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

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

希望能帮助到你.


Jul*_*usG 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;
Run Code Online (Sandbox Code Playgroud)

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
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我必须注意`.pragma library` _allowes_ JS文件将被多个QML文件使用,但_不能保证_只有一个库实例.我刚刚在我的应用程序中遇到了严重错误,这是由于我尝试将JS库用作全局状态容器. (5认同)
  • 不要忘记把`#pragma library` 放在那里。 (2认同)

cez*_*tko 5

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

qml/
??? <ModuleName>/
? ??? <ClassName>.qml
? ??? qmldir
Run Code Online (Sandbox Code Playgroud)

在main.cpp中你有:

QQmlApplicationEngine engine;
engine.addImportPath("qrc:/qml");    // Can be any directory
engine.load("qrc:/qml/main.qml");
Run Code Online (Sandbox Code Playgroud)

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

<RCC>
 <qresource prefix="/">
      (...)
 <file>qml/main.qml</file>
 <file>qml/MySingletons/MySingleton.qml</file>
 <file>qml/MySingletons/qmldir</file>
 </qresource>
</RCC>
Run Code Online (Sandbox Code Playgroud)

在qmldir中:

module MySingletons
singleton MySingleton 1.0 MySingleton.qml
Run Code Online (Sandbox Code Playgroud)

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

import MySingletons 1.0
Run Code Online (Sandbox Code Playgroud)

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