参考文章地址 : How to make a QML Component a Singleton?
大致意思是怎么创建一个qml控件单例(有两种方法,一种是c++函数,另一种是在qml文件和qmldir文件上下功夫)
首先,由于qml中没有常量的概念(只能通过c++拓展),也没有自定义全局的方法(也只能通过c++方式).
这里取一个简单的例子,例如在设计UI界面时,我们通过使用FontLoader来加载字体,但是,在每一个UI-Component中设置font.family时就会发生重复构建FontLoader。
==============================
在Button.qml中
Button{
font.family:fontLoader.name;
FontLoader{
id:fontLoader;
source:"./myfont.ttf";
}
}
在 Input.qml中
Input{
font.family:fontLoader.name;
FontLoader{
id:fontLoader;
source:"./myfont.ttf";
}
}
一般在UI设计中都会使用同一套字体,但是这里却发生重复构建FontLoader的事情,于是我们想要在qml怎么减少重复构建一个相同元素(c++中直接注册对象到运行上下文)。但是在纯qml项目中怎么实现呢?
下面通过一个例子来简单说明一下
+ ..
+ singleton
| singleton.qmlproject
| + Global
| | SingletonObject.qml
| | qmldir
| main.qml
这个项目的结构是一个最简单的带有自定义qml模块的qml项目(关于qml项目怎么进行模块化管理,请看 这里)
我们直接看项目下的SingletonObject.qml
/*
* pragma Singleton
* 上诉关键语句表明在一个qml应用程序中,本qml文件所代表的的对象只创建一次,
* 类似于一个全局静态单例对象
* 注意pragma Singleton要和qmldir文件配套使用
* 在qmldir文件添加一句
* singleton SingletonObject 1.0 ./SingletonObject.qml
*
*/
pragma Singleton
import QtQuick 2.0
QtObject{
// public:
readonly property string singletonString: "this is singleton object !";
readonly property alias font: textShow.font;
//private
property Text __text: Text {
id:textShow;
font.family: fontLoader.name;
}
property FontLoader __fontLoader: FontLoader {
id:fontLoader;
}
Component.onCompleted: {
console.debug("SingletonObject only create once");
}
}
(上述对象的属性使用了一些内建的element,文章看这里
QML的property支持的类型
)这里qml文件的开头是一句
pragma Singleton
这句话是声明本qml文件是作为一个单例对象,不允许被构建多次
看看qmldir文件
module Global
singleton SingletonObject 1.0 ./SingletonObject.qml
因为使用qml单例需要在模块中声明才可使用,singleton SingletonObject 1.0 ./SingletonObject.qml,这句语法声明单例的名字,版本和文件
然后再看看singleton.qmlproject
/* File generated by Qt Creator */
import QmlProject 1.1
Project {
mainFile: "main.qml"
/* Include .qml, .js, and image files from current directory and subdirectories */
QmlFiles {
directory: "."
}
JavaScriptFiles {
directory: "."
}
ImageFiles {
directory: "."
}
/* List of plugin directories passed to QML runtime */
importPaths: [ "./" ] // qmldir file was in project root path's child path.
}
使用QtCreator中自动生成,要手动添加模块路径,qmldir的文件时在项目路径下的一个子文件夹里,这个子文件夹及内部文件就是模块。
最后看看main.qml
import QtQuick 2.4
import Global 1.0;
Item{
Component.onCompleted: {
console.debug(SingletonObject.singletonString);
}
//SingletonObject{} //! [error] Composite Singleton Type SingletonObject is not creatable.
}
控制台打印
Starting E:\SDK\Qt5SDK\5.4\mingw491_32\bin\qmlscene.exe...
qml: SingletonObject only create once
qml: this is singleton object !
如果修改main.qml如下
import QtQuick 2.4
import Global 1.0;
Item{
Component.onCompleted: {
console.debug(SingletonObject.singletonString);
}
SingletonObject{} //! [error] Composite Singleton Type SingletonObject is not creatable.
}
则会构建失败,控制台提示如下
Starting E:\SDK\Qt5SDK\5.4\mingw491_32\bin\qmlscene.exe...
file:///E:/Qt5/singleton/main.qml:8 Composite Singleton Type SingletonObject is not creatable.
这里的意思是被声明为单例类型的element不能被重复创建。
例子下载