qgroundcontrol是用qt的qml写成的地面站程序,要看清楚基本框架不容易,研究整两日,记录下要点:
首先要清楚基本的概念:
关于qml
Qt QML模块/qml语言/qt quick语言库
QML是一种开发语言,主要功能是行程一种可跨平台调用的界面,同时它支持与C++语言交互,与javscript交互
QML是一种描述性语言,可读性很强,类似于xml,其内部可定义函数,变量等
Qt QML模块是qml的引擎,底层实现其语法等支持工作
qt quick 是QML的基本类库提供QML的基本模块,在qml文件中,一般会import qtquick
关于qml与c++的交互
qmlRegisterType 是一个可以将C++实现的类在QML中调用的,连接C++和QML的一个工具,非常重要的函数。
int qmlRegisterType(const char * uri, int versionMajor, int versionMinor, const char * qmlName)
可以看到qmlRegisterType里总共4个参数,第一个参数* uri指的是QML中import后的内容,相当于头文件名,第二个第三个参数分别是主次版本号,第四个指的是QML中类的名字。
下面举个例子
在main.cpp文件中
#includeqmlRegisterType("com.mycompany.qmlcomponents", 1, 0, "Slider");
在main.qml文件中:
import com.mycompany.qmlcomponents 1.0
Slider {}
qgc的主界面载入过程
所以在gqc官方的开发者说明中如是说:
QGC中UI设计的主要模式是用QML编写的UI页面,多次与用C ++编写的定制“控制器”进行通信。类似MVC的设计模式。
所以在主程序中做了几件事,完成整个程序的加载:
1、载入根节点的qml,由qml完成具体的界面载入过程;
2、实现各种“控制器”;
3、将控制器注册到qml中;
详解
1、载入根节点的qml,由qml完成具体的界面载入过程;
//文件QGCCorePlugin.cc,用QQmlApplicationEngine载入MainWindowNative.qml
QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent)
{ QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(parent);
pEngine->addImportPath("qrc:/qml");
pEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
pEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainWindowNative.qml")));
return pEngine;}
//文件MainWindowNative.qml,用Loader载入mainWindowInner
Loader {
id: mainWindowInner
anchors.fill: parent
source: "MainWindowInner.qml"
Connections { target: mainWindowInner.item onReallyClose: { _forceClose = true _rootWindow.close() } } }
//文件MainWindowInner.qml载入了 -- Main UI
2、实现各种“控制器”;
就是在src中的各种c++类如,CameraCalc,QmlObjectListModel等
3、将控制器注册到qml中;
//在文件QGCApplication中,用函数qmlRegisterType注册了大量的库,方便后面与qml交互
void QGCApplication::_initCommon(void){
QSettings settings;
// Register our Qml objects
qmlRegisterType("QGroundControl.Palette", 1, 0, "QGCPalette");
qmlRegisterType ("QGroundControl.Palette", 1, 0, "QGCMapPalette");
。。。。
}