总的来说,需要完成那些事呢?
- 首先,您需要在QML脚本中使用pragma Singleton关键字,
- 然后您需要将该组件注册为单例,
- 最后您需要将它导入到需要使用他的其它QML文件中。
第一步:将一个QML组件声明为单例
假设以下使我们将要进行单例的文件
//MyStyleObject.qml
import QtQuick 2.0
Item {
readonly property string colourBlue: "blue"
readonly property string colourRed: "red"
readonly property int fontPointSize: 16
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
要将其进行单例化,首先您需要在首行添加如下语句
//MyStyleObject.qml
pragma Singleton //注意这里
import QtQuick 2.0
Item {
readonly property string colourBlue: "blue"
readonly property string colourRed: "red"
readonly property int fontPointSize: 16
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
第二步:注册组件
现在您有两种选择
- 您可以在C++中注册组件,
- 或者使用qmldir文件。
C++中实现
要在您的C ++代码的某个地方通过C ++注册单例,您需要调用qmlRegisterSingletonType()
。
#include <QtQml>
...
qmlRegisterSingletonType( QUrl("file:///absolute/path/MyStyleObject.qml"), "ca.imaginativethinking.tutorial.style", 1, 0, "MyStyle" );
...
- 1
- 2
- 3
- 4
QML中实现
如果将调用添加到qmlRegisterSingletonType()
不适用于您,也许这是一个Qt Quick UI项目(即没有C ++),那么您可以将名为qmldir
的文件添加到MyStyleObject.qml
文件所在的目录。 在导入目录时,QML引擎首先查找qmldir文件并使用它导入在该目录中找到的脚本; 如果该文件不存在,它将导入使用默认值(即非单例并使用文件名称作为组件名称)找到的脚本。 qmldir文件可以定义不同的名称来代替文件名,还可以指示将脚本注册为单例。
目录结构应该如下所示:
/root
+ absolute
| + path
| | + qmldir
| | + MyStyleObject.qml
| | + AnotherObject.qml
| | + MyButton.qml
| | + MySwitch.qml
| + main.qml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
以下是qmldir应该有的样子:
singleton MyStyle 1.0 MyStyleObject.qml
MyOtherObject 1.0 AnotherObject.qml
MyButton 1.0 MyButton.qml
- 1
- 2
- 3
请注意,如果在目录中找到脚本但未在qmldir文件中声明脚本,它仍会导入,但使用默认设置。 MySwich.qml将被导入并使用名称MySwitch注册为非单例。 您可以在这里看到,我们也可以使用qmldir来定义组件的文件名之外的其他名称,MyButton被注册为使用默认的文件名,但AnotherObject.qml被注册为使用名称MyOtherObject。
第三步:导入并使用单例
C++中实现
如果您使用上面的C ++选项,那么为了在您的QML脚本中导入和使用单例,您需要通过qmlRegisterSingletonType()
的第二个参数导入您定义的模块,然后使用注册名称(参数三qmlRegisterSingletonType
))。
//main.qml
import QtQuick 2.0
import wanywhn.style 1.0
Rectangle {
anchors.fill: parent
color: MyStyle.colourBlue // <-- 注意这里
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
QML中实现
如果您使用qmldir方法,那么您只需导入文件所在的目录。
//main.qml
import QtQuick 2.0
import "path"
Rectangle {
anchors.fill: parent
color: MyStyle.colourBlue // <-- 注意这里
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
但是请注意,如果main.qml位于路径目录中,您仍然必须导入该路径,因为当您依靠自动查找时,qmldir文件不会被使用。
那么使用效果如何呢?
代码地址
让我们尝试创建一千个方块。当然这里会有两种方式
Component {
id: gridDelegateUsingAnInstanceStyleObject
Rectangle {
width: 50
height: width
color: myStyle.colourBlue
border.color: myStyle.colourRed
border.width: myStyle.borderSize
Text {
anchors.centerIn: parent
text: index
font.pointSize: myStyle.fontPointSize
color: myStyle.colourWhite
}
MyStyleObject {
id: myStyle //<-- 注意这里,当您使用myStyle时,他指向一个实例对象
}
}
}
Component {
id: gridDelegateUsingASingletonStyleObject
Rectangle {
width: 50
height: width
color: MyStyle.colourBlue //<-- 注意当使用MyStyle(大写字母M)时,您指的是qml目录文件中定义的单例。
border.color: MyStyle.colourRed
border.width: MyStyle.borderSize
Text {
anchors.centerIn: parent
text: index
font.pointSize: MyStyle.fontPointSize
color: MyStyle.colourWhite
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
分别使用这两个delegate,使用QML 分析器查看效果
效果
不用说都清楚了吧。;)