我想在配置文件中声明一个全局属性并在其他文件中使用它。例如声明mainbg
:
样式.qml:
property color mainbg: 'red'
并在其他 QML 文件(如view.qml
和main.qml
)中使用它。我怎样才能完成这项工作?
我想在配置文件中声明一个全局属性并在其他文件中使用它。例如声明mainbg
:
样式.qml:
property color mainbg: 'red'
并在其他 QML 文件(如view.qml
和main.qml
)中使用它。我怎样才能完成这项工作?
使用 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 文件)。
基本上,如果您不需要属性绑定(如果您的值是一个常量并且不需要在更改时通知),您可以在 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 对象中,根据定义,它是全局的。
希望能帮助到你。
您可以创建一个 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
}
}
添加一些有助于@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.
在 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
您始终可以创建一个新的 QML 对象文件,其中包含您希望跨 qml 文件共享的属性。只需以与任何 QML 对象相同的方式导入它,您就可以访问属性。现在,如果您希望能够修改这些属性并在实例之间共享更改,事情会变得更加棘手,您很可能需要使用 .pragma 库 js 文件的某种解决方案。除非您想编写某种 C++ 替代方案。