QGC地面站二次开发(二)QGC 界面自定义和修改 |
您所在的位置:网站首页 › linux_logo自定义 › QGC地面站二次开发(二)QGC 界面自定义和修改 |
目录 1、QGC 地面站的显示机制 1.1、C++类注册为 qml 可访问类型 1.2、注册属性或者方法 1.1.1、 属性声明 1.1.2、方法声明 2、QGC 地面站界面初步修改 3、QGC 地面站菜单和 LOGO 修改 3.1、地面站菜单 3.2、Logo 修改 3.2.1、 Windows Logo 3.2.2、 Linux Logo 4、QGC 地面站菜单功能裁剪 4.1、File 菜单 4.1.1、 日志回放 4.1.2、 退出 4.2、Widget 菜单项 4.3、五大页面 1、QGC 地面站的显示机制QGC 显示入口是 MainWindow Widget,加载了 MainWindowHybrid.qml,开始了整个 qml 文件调用系统, 再 MainWindowHybrid.qml 通过 Loader 器加载了 MainWindowInner.qml 在该文件系统中,该文件中完成了主页面的布局。 MainWindowInner.qml 中 MainToolBar 控件位于页面的顶部, 包含了5 大主页面的切换按钮,当鼠标点击时,对 onClicked 事件处理,通过Loader 来加载相应的 qml 文件,页面和 qml 文件的对应关系参看下图:QGC 地面站显示逻辑 QGC 将 QGroundControlQmlGlobal 类构造为单例,在 qml 声明 importQGroundControl 1.0 来引入相关的内容,之后通过 QGroundControl 来访问相应的属性和方法。 为方便大家的使用,在此我给大家介绍一下 Qt 中 C++属性和方法的定义方式。对于 C++中自定义的类如果想要在 qml 中被访问需要满足下面的条件:1. C++类继承自 QObject 或者 Qobject 的父类 2. 添加 Q_OBJECT 字段 我们可以通过下面的两种方式将 C++的类声明为 qml 中可以访问的类型: 1. qmlRegisterUncreatableType 声明的类型可以被 qml 通过属性方式访问,却无法qml 中直接构造。 使用示例如下: qmlRegisterUncreatableType("QGroundControl .MultiVehicleManager", 1, 0, "MultiVehicleManager", "Reference only");QGroundControlQmlGlobal.h 中将 MultiVehicleManager 通过下面的语句 声明为它的属性: Q_PROPERTY(MultiVehicleManager* multiVehicleManager READ multiVehicleManager CONSTANT)Qml 中课题通过 QGroundControl.multiVehicleManager 来访问其中的属 性和方法2. qmlRegisterType 声明的 C++类型可以在 qml 文件中直接构造,在 qml 中通过 id来访问属性和方法。 qmlRegisterType ("QGroundControl.Controllers", 1, 0, "PlanMasterController");PlanView.qml 中: PlanMasterController { id: masterController ……} 1.2、注册属性或者方法通过上面的方式我们将一个 C++类注册入 Qt 的元对象系统中 ,在 C++类中我们可以通过Q_PROPERTY 注册属性,同时可以通过在函数声明前添加Q_INVOKABLE 来声明 qml 可以调用的方法。 1.1.1、 属性声明主要存在以下几种形式(示例取自 Vehicle 类,大家在实践过程中可以参考其中的实现进行): 1. Q_PROPERTY(int id READ idCONSTANT)当该属性的值一旦被赋值,在整个程序运行期间,在我们的 C++承租中不会修改该参数值时,我们采用这样的表达式。 2. Q_PROPERTY(QGeoCoordinate coordinate READ coordinate NOTIFY coordinateChanged) 当该属性只会在 C++中改变该属性的值的时候,我们会采用这样的表达式,当我们在 C++中改变该参数值时,发射 coordinateChanged 信号, 来通知 qml 相关的属性有更改 i 进而实现相关的状态更改。 3. Q_PROPERTY(bool armed READ armed WRITE setArmed NOTIFY armedChanged)当该属性在 C++和 qml 都会改变该属性的值的时候,我们会采用这样的表达式,当我们在 C++中改变该参数值时,发射 armedChanged 信号,来通知 qml 相关的属性有更改进而实现相关的状态更改。 同样地在 qml 中我们通过 id.armed = true,此时会出发 C++中的 setArmed 函数,来实现相关状态的更改。 1.1.2、方法声明方法声明只需要我们在函数定义前面添加 Q_INVOKABLE 即可。如: Q_INVOKABLE void emergencyStop(void); 2、QGC 地面站界面初步修改这一节我给以示例的形式介绍一下在飞行页面的 Fly 那一列下方添加一个矩形框,在鼠标点击触发 QGC 发送发送向飞机请求全参指令,然后再 QGC 的模拟飞控 Mock 连接中将接收到的 QGC 的请求信息打印出来,进而完成整个回路的验证 1. 添加一个矩形框,在FlightDisplayView.qml 中, Fly 操作栏对应的组件 id 是 toolStrip Rectangle{ //该控件的左侧和 toolStrip 的左侧对齐 anchors.left: toolStrip.left //该控件的顶部位于 toolStrip 的底部 anchors.top: toolStrip.bottom //控件顶部设置一个留白间隔 anchors.topMargin: _margins * 2 //设置控件的宽度、高度、颜色 width: 200 height: 40 color: "red" //为控件设置一个圆弧 radius: 4 visible: true //为控件设置层级,层级低的可能会被层级高的遮挡而无法看到 z: _panel.z + 4 Text{ //为控件添加一个 text 区域,进行文本显示 anchors.fill: parent text: qsTr("Request All Parameters") } MouseArea{ //为整个控件覆盖一个鼠标操作区域,鼠标点击触发 clicked 事件, 通过 onClicked 处理相关的事件 anchors.fill: parent onClicked: { console.log("Request all Parameter is clicked!") QGroundControl.multiVehicleManager.activeVehicle.requestAllParameters() } } } 2. 在 Vehicle 中添加函数实现 Vehicle.h 中添加函数定义: Q_INVOKABLE void requestAllParameters(void);Vehicle.cc 中完成函数的实现: void Vehicle::requestAllParameters() { mavlink_message_t msg; mavlink_msg_param_request_list_pack_chan( _mavlink->getSystemId(), _mavlink->getComponentId(), priorityLink()->mavlinkChannel(), &msg,_id,MAV_COMP_ID_ALL); sendMessageOnLink(priorityLink(), msg); qDebug() if (advanced) { menuBar()->addMenu(_ui.menuFile); menuBar()->addMenu(_ui.menuWidgets); menuBar()->addMenu(_ui.menuoptions); } else { menuBar()->clear(); } }在MainWindow.cc 的添加函数定义执行相关修改: void MainWindow::selectIndoorMode(bool in) { qgcApp()->_loadCurrentStyleSheet(); QGCPalette::setGlobalTheme(in ? QGCPalette::Dark : QGCPalette::Light); }在MainWindow.h 添加槽函数: protected slots: void selectIndoorMode(bool in);MainWindow.cc 构造函数中将点击触发的 triggered 和自定义的操函数绑定: connect(_ui.indoor, &QAction::triggered, this, &MainWindow::selectIndoorMode); 3.2、Logo 修改 3.2.1、 Windows LogoQGC 中 windows 加载 Logo 在 qgroundcontrol.pro 中 WindowsBuild { RC_ICONS = resources/icons/qgroundcontrol.ico } 3.2.2、 Linux LogoQGC 中 Linux 加载 Logo 在 main.cc 中 #ifdef Q_OS_LINUX QApplication::setWindowIcon(QIcon(":/res/resources/icons/qgroundcon trol.ico")); #endif选择 Logo 图片,添加进 qrc 资源文件中,更改对应的 logo 文件路径。 如果你的图片过大可以利用该网址 http://www.uupoop.com/ico/?action=make 进行转换。 选好 ico 后添加到资源文件中。 QGC 的菜单栏包含 File 和 Widget 两项,下面对这两项进行一个详细介绍 4.1、File 菜单在 MainWindow.ui 总添加了 id 分别为 actionStatusBar(日志回放)actionExit(退出)两个按钮: 4.1.1、 日志回放在 MainWindow 的构造函数中通过connect(_ui.actionStatusBar, &QAction::triggered, this,&MainWindow::showStatusBarCallback);将用户点击的动作和 showStatusBarCallback 函数绑定,来执行相关的操作。 4.1.2、 退出![]() Widget 下拉子菜单时通过 MainWindow 的 C++代码中实现的,如果想要对菜单项裁剪只要 rgDockWidgetNames 相应的项注释掉即可。 static const char *rgDockWidgetNames[] = { "MAVLink Inspector", "Custom Command", "Onboard Files", "HIL Config", "Analyze" }; for (int i = 0, end = ARRAY_SIZE(rgDockWidgetNames); i < end; i++) { const char* pDockWidgetName = rgDockWidgetNames[i]; // Add to menu QAction* action = new QAction(pDockWidgetName, this); action->setCheckable(true); action->setData(i); connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction); _ui.menuWidgets->addAction(action); _mapName2Action[pDockWidgetName] = action; } 4.3、五大页面QGC 默认进入的时 Fly 页面,用户可以通过菜单栏下方的额五个按钮实现不同页面的切换, MainToolBar.qml 实现了五大按钮的横向布局,并监听鼠标的点击 onClicked 事件,发射出相应的信号,如 showSettingsView 等,在MainWindowInner.qml 中对相应的信号处理,加载不同的页面。按钮的对应关系在 MainToolBar.qml 参看下文。 Row { …… //APPlication Setting QGCToolBarButton { source: "/res/QGCLogoWhite" onClicked: toolBar.showSettingsView() …… } // Vehicle Setup QGCToolBarButton { …… source: "/qmlimages/Gears.svg" onClicked: toolBar.showSetupView() …… } //Plan QGCToolBarButton { source: "/qmlimages/Plan.svg" onClicked: toolBar.showPlanView() …… } //Fly 页面 QGCToolBarButton { source: "/qmlimages/PaperPlane.svg" onClicked: toolBar.showFlyView() …… } //Analyze 页面 QGCToolBarButton { source: "/qmlimages/Analyze.svg" onClicked: toolBar.showAnalyzeView() …… } …… } 如果您想要裁剪某个页面只需要将对应的 QGCToolBarButton 控件的实现代码注释或者删除即可。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |