QML之全局变量
C++形式
-
根据功能定义不同类,例如:程序设置类:
class Settings : public QObject{ Q_OBJECT public: Q_PROPERTY(QString appName MEMBER m_appName) private: QString m_appName = "MyApp"; }
-
和网络类:
class Networks : public QObject{ Q_OBJECT }
-
定义一个总的类:
class GlobalObject : public QObject{ Q_OBJECT public: Q_PROPERTY(Settings* settings MEMBER m_settings) Q_PROPERTY(Networks* networks MEMBER m_networks) private: Settings* m_settings; Networks* m_networks; }
-
在main函数中创建总类的对象:
auto globalObject = new GlobalObject();
-
在QQmlEngine构建之后还未加载任何QML文件之前,将该对象设置为执行上下文对象:
engine->rootContext()->setContextObject(globalObject);
QML中约定,contextObject的所有属性都自动变为contextProperty,
就像他们用第一种方法单独定义一样。所以如果需要的功能比较多,建议使用批量定义的方法,更方便快捷。
需要注意,如果一个程序中同时使用了这两种方法定义全局变量而且有变量重名了,那么以单独定义的优先。
QML形式
-
将这些C++类注册到QML中:
qmlRegisterType<Settings>("MyCppBackend", 1, 0, "Settings"); qmlRegisterType<Networks>("MyCppBackend", 1, 0, "Networks");
-
然后新建一个QML文件:
//globalobject.qml import QtQuick 2.7 import MyCppBackend 1.0 QtObject { id: root property var $settings: Settings{ } property var $networks: Networks{ } }
-
将该QML文件作为QML引擎加载的第一个文件:
engine->load(QUrl("qrc:///globalobject.qml"));
QML引擎约定,加载的第一个QML文件就是contextObject,所以和C++定义类似,它的属性也就成了contextProperty。
两种方法比较
和C++批量定义相比,QML批量定义有如下优势:
变量名前面可以加$,从而方便区分全局变量和局部变量,这个在C++定义属性的时候是不允许的;
如果某个全局变量(一般是QML对象)构造很慢,可以通过QML中的Loader来很方便异步构造,从而加速程序启动:
property var loader: Loader{
asynchronous: true
source: "qrc:/UI/Main.qml"
onLoaded: {
// 当加载完毕会进入这里
}
}