QML 将一个qml文件定义为公共的全局单例
在c++中,可以将一个类定义为单例,然后其内部可以定义很多公共的函数或者变量供全局使用;
那么在qml中,其实也是可以有类似的操作的,例如新建一个qml文件,主要存储全局通用的函数、属性变量、信号等,为整个项目调用;
还有一个最重要的作用就是,当两个qml文件毫无关联时,但是a.qml需要触发b.qml某个动作时,就可以使用到全局单例做中转操作了;
例如在a.qml中触发单例里面的某个信号,在b.qml中绑定触发槽函数即可。
1 在项目中,新建一个BasicConfig.qml文件,为了模块化,新建一个文件夹basic,将文件新建在此;
/basic/BasicConfig.qml
填写BasicConfig.qml代码:
// 第一步,固定文本填写
pragma Singleton // 这一行是必须写的import QtQuick 2.0QtObject {// 属性变量property int windowWidth: 1024// 函数:两数相加function funcAdd(a, b) {return a + b;}// 信号signal mySignal(int a);
}
2 然后继续新建一个空文件,没有后缀
填写qmldir代码:(名字可随意取,这里取名为:qmldir,如上图新建在BasicConfig.qml同级路径)
// 第三步
singleton BasicConfig BasicConfig.qml
3 在main.cpp中注册
#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);// 第二步:注册qml全局单例qmlRegisterSingletonType(QUrl("qrc:/BasicConfig.qml"), "BasicConfig", 1, 0, "BasicConfig");return app.exec();
}
4 导入
在需要使用的地方导入文件夹路径即可
import "./basic"
5 测试代码
import "./basic"Window {id: rootvisible: truewidth: 1280height: 800title: qsTr("Hello World")Component.onCompleted: {console.log(BasicConfig.funcAdd(10, 20))console.log(BasicConfig.windowWidth)}
}
编译输出:
可以正常使用了!
并且BasicConfig是单例的,不可以再定义这个组件了,如果定义就会编译报错:
在使用时,只能通过BasicConfig去使用,避免了定义多个组件的问题!
总结:
通过创建BasicConfig.qml文件,使用pragma Singleton声明单例,并定义全局属性、函数和信号。配合qmldir文件配置和main.cpp中的注册,可以像C++单例一样在项目各处调用。使用时只需导入路径,通过BasicConfig访问全局内容,且无法重复定义该组件。该方法有效实现了QML中的单例管理,便于维护全局状态和共享功能。