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

问题描述:

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

Style.qml

property color mainbg: 'red' 

并且在其它QML文件使用它(如view.qmlmain.qml)。我该如何做这项工作?

使用QML单例。

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

这些都是你所需要的碎片:

风格。QML

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

qmldir

此文件必须在同一文件夹中的单身.qml文件(在我们的例子中Style.qml),或者必须给出相对路径。 qmldir也可能需要包含在.qrc资源文件中。有关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文件)。

+0

为什么不只是一个简单的'.pragma库'JavaScript文件? – Matteo 2018-02-22 16:15:13

您可以创建一个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 
    } 
} 
+1

不要忘记把'#pragma库'放在那里。 – user1095108 2013-03-07 07:43:58

+5

我必须注意到'.pragma library' _allowes_ JS文件被几个QML文件使用,但_不能保证只有一个库实例。我刚刚在应用程序中遇到了严重的错误,这是因为我尝试将JS库用作全局状态容器。 – tonytony 2015-08-12 11:43:54

你总是可以创建一个包含要跨QML文件共享属性的新QML对象文件。只需将其导入任何QML对象,并且您都可以访问属性。现在,如果您希望能够修改这些属性并在实例间共享更改,那么事情会变得更加棘手,您很可能会想要使用.pragma库js文件进行某种解决方案。除非你想写一些C++的选择。

基本上,如果你(如果你值是一个常数,不会需要是在变化呈报),你可以在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对象中。

希望它有帮助。

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

,或者如果你想组属性在QML 添加它们包括主要是QML并给出一个ID,现在你可以使用该ID

main.qml

Item{ 
width:10 
height:10 

Model{ 
id:globdldata 
} 



} 
访问此属性

Model.qml

Item { 

property color mainbg: 'red' 

} 

可以使用globdldata.mainbg随时随地

添加一些贡献@pixelgrease答案,我发现另一种技术,不需要相对路径import ".",解决bug QTBUG-34418。如果使用qmldir和singleton类与使用单例的qml文件不同,那么这非常有用。该技术需要在树结构中定义一个适当的模块:然后通过将模块的父路径添加到带有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文件erate:

import MySingletons 1.0 

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