文章目录
- 前言
- 一、课程大纲
- 二、修改软件名称
- 三、修改软件图标
- 四、官方QGC中文版BUG修复
- 五、汉化
- 六、修改商标
- 七、添加信号-槽
- 1、添加文件到QGC工程
- 2、添加界面
- 3、QML和C++交互
- 4、信号与槽
- 5、测试
- 八、添加QML和C++交互
- 九、MAVLINK的解析与发送
- 十、换地图
- 十一、添加自定义mavlink消息
- 十二、在主工具栏添加一个自定义图标
- 十三、解析自定义mavlink数据并在自定义图标上显示
- 十四、同时显示多机轨迹
- 十五、在地图上画一个点
前言
QGC版本:4.2.4稳定版
需要的基础:少量的C++、QT基础
飞控固件:PX4、Ardupilot
课程答疑微(18362086993)
课程所用虚拟机(已配置好开发环境)
链接:https://pan.baidu.com/s/12zes9Jk2OB_c2ghNsAKv1w?pwd=7o4u
提取码:7o4u
–来自百度网盘超级会员V6的分享
VMware下载(使用VM17)
链接:https://pan.baidu.com/s/1lBCMX1O3U-T64gzM5c0IYg?pwd=ylf6
提取码:ylf6
–来自百度网盘超级会员V6的分享
虚拟机的安装和打开:
https://cwkj-tech.yuque.com/bsge84/uav-m1/cuut9sq5sci8c5wr#rdB9k
独家汉化版QGC下载地址:
链接:https://pan.baidu.com/s/16G97kfid-tDQq2kZCEYjnQ?pwd=es97
提取码:es97
–来自百度网盘超级会员V6的分享
编译环境安装可以参考:
6.1、QGC编译环境安装(ubuntu)
课程目录(暂时想到这么多,后续会不断更新)
一、课程大纲
二、修改软件名称
改一行代码就行
修改
QGCApplication.cc
setApplicationName("cwkj");
修改后效果如下:
三、修改软件图标
添加图片资源
新建一个文件夹img_add,放入需要添加的图片资源
然后在qgcimages.qrc中点击添加->添加文件,选择上面添加的图片,然后填写别名,回车然后ctrl+s保存qgcimages.qrc
然后就可以在程序中使用添加的图片了,注意程序中填写的是图片的别名。
修改主工具栏图标:
修改MainToolBar.qml,在下图位置修改图片资源的路径为自己添加的资源(以软件设置按钮为例):
icon.source: "/qmlimages/软件图标.png"
效果如下:
修改软件设置图标:
修改MainRootWindow.qml
需要修改两个地方:
showTool(qsTr("Application Settings"), "AppSettings.qml", "/qmlimages/软件图标.png")
imageResource: "/qmlimages/软件图标.png"
四、官方QGC中文版BUG修复
QGC中文bug解决教程
五、汉化
打开QGC源码工程,点击工具->外部->Linguist->Update Translations(lupdate),弹窗选全是
然后打开Qt Linguist
在Qt Linguist中点击file->open,打开汉化脚本
打开后,在左侧会显示总个数和已汉化的个数,点击没有全部汉化的Context,在右侧对有问号的进行汉化,在简体中文下面的输入框写入对应的汉化结果,然后点击上方的勾号,勾完后对应的问号就变成了勾号,然后点击上方的保存按钮。
保存后打开QGC工程源码,如果出现下面的提示,选全是,然后编译
编译后效果如下:
六、修改商标
修改PX4FirmwarePlugin.h下图位置,将图片改成自己想显示的图片:
QString brandImageIndoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/软件图标.png"); }
QString brandImageOutdoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/软件图标.png"); }
修改后效果如下:
七、添加信号-槽
1、添加文件到QGC工程
在qgroundcontrol/src目录下创建SimpleTest文件夹
在文件夹中创建SimpleTest.cpp
、SimpleTest.h
和SimpleTest.qml
三个文件
在qgroundcontrol.pro
中添加下图位置添加src/SimpleTest/SimpleTest.h\
下图位置添加src/SimpleTest/SimpleTest.cpp\
然后即可将添加的test.cpp和test.h编译到QGC中。
SimpleTest.cpp
填入内容如下:
#include "SimpleTest.h"
#include <QtCharts/QLineSeries>
#include<qdebug.h>
SimpleTest::SimpleTest()
{
connect(this,&SimpleTest::valueChanged,this,&SimpleTest::_test);
}
SimpleTest::~SimpleTest()
{
}
void SimpleTest::setTest1(QString test)
{
_test1=test;
qDebug()<<test;
emit valueChanged();
}
void SimpleTest::setTest2(QString test)
{
_test2=test;
qDebug()<<test;
emit valueChanged2();
}
void SimpleTest::_test()
{
qDebug()<<"in C++ slot";
emit _testChanged();
}
SimpleTest.h
填入内容如下:
#pragma once
#include <QObject>
#include <QString>
#include <QMetaObject>
#include <QStringListModel>
// Fordward decls
class Vehicle;
class SimpleTest : public QObject
{
Q_OBJECT
public:
SimpleTest();
virtual ~SimpleTest();
Q_PROPERTY(QString test1 READ test1 WRITE setTest1 NOTIFY valueChanged)
Q_PROPERTY(QString test2 READ test2 WRITE setTest2 NOTIFY valueChanged2)
QString test1 ()
{
return _test1;
}
QString test2 ()
{
return _test2;
}
void setTest1(QString test1);
void setTest2(QString test2);
signals:
void valueChanged();
void valueChanged2();
void _testChanged();
private slots:
void _test(void);
private:
QString _test1="A";
QString _test2="a";
};
SimpleTest.qml
填入内容如下:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.Palette 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
import SimpleTest 1.0
AnalyzePage {
id: mavlinkConsolePage
pageComponent: pageComponent
pageName: qsTr("SimpleTest")
SimpleTest {
id: _SimpleTest
}
Connections
{
target: _SimpleTest
function on_testChanged()
{
_SimpleTest.test2="c"
}
}
TextEdit {
id: textEdit
x: 285
y: 189
width: 81
height: 25
color: "#f5f3f3"
text: qsTr(_SimpleTest.test1)
font.family: "Times New Roman"
font.pixelSize: 12
}
TextEdit {
id: textEdit1
x: 285
y: 229
width: 81
height: 25
color: "#f5f3f3"
text: qsTr(_SimpleTest.test2)
font.family: "Times New Roman"
font.pixelSize: 12
}
Button {
id: button
x: 372
y: 189
text: qsTr("发送")
onClicked: {
_SimpleTest.test1="C"
}
}
}
2、添加界面
在qgroundcontrol.qrc中将上面创建的QML资源添加进去,点击Add Files选择上面创建的QML文件。取别名叫SimpleTest.qml。注意添加完后一定不要忘了把下面别名那个输入框填上别名,注意别名不要写错,不要忘了加上后缀.qml。否则如果后面QGCCorePlugin.cc引用的时候和别名不一样,会导致页面里是空的
然后修改QGCCorePlugin.cc文件
添加一行
_p->analyzeList.append(QVariant::fromValue(new QmlComponentInfo(tr("SimpleTest"), QUrl::fromUserInput("qrc:/qml/SimpleTest.qml"), QUrl::fromUserInput("qrc:/qmlimages/MavlinkConsoleIcon"))));
3、QML和C++交互
1.C++类如果想被QML访问,需要满足两个条件:
(1)继承自QObject类
(2)添加Q_OBJECT宏
对应本例如下:
2.C++实例注册到qml
QT可以通过qmlRegisterUncreatableType或者qmlRegisterType将 C++的类声明为 qml 中可以访问的类型:
首先在QGCApplication.cc
中添加头文件:
#include "SimpleTest/SimpleTest.h"
(1)qmlRegisterType
qmlRegisterType 声明的 C++类型可以在 qml 文件中直接构造,在 qml 中通过 id来访问属性和方法。
qmlRegisterType里总共4个参数:第一个参数指的是QML中import后的内容,相当于头文件名;第二个第三个参数分别是主次版本号;第四个指的是QML中类的名字。
在本例中,在QGCApplication.cc
中下图位置添加:
qmlRegisterType<SimpleTest> ("SimpleTest", 1, 0, "SimpleTest");
然后先在SimpleTest.qml
中import SimpleTest 1.0
,再
SimpleTest {
id: _SimpleTest
}
就可以通过_SimpleTest
访问SimpleTest
类中的属性和方法。
注册属性或者方法
通过上面的方式将 C++类注册入 Qt 的元对象系统中后 ,可以通过 Q_PROPERTY 注册qml 可以调用的属性,同时可以通过在函数声明前添加Q_INVOKABLE 来声明 qml 可以调用的方法。
属性声明
主要存在以下几种形式:
Q_PROPERTY(int
test
READ
test
CONSTANT)
当该属性的值一旦被赋值,在整个程序运行期间 C++中不会修改该属性。
Q_PROPERTY(int
test
READ
test
NOTIFY valueChanged)
这种方法声明的属性只有在C++中会更改,当更改时,发射 valueChanged 信号来通知 qml 。
Q_PROPERTY(int
test
READ
test
WRITE
settest
NOTIFY valueChanged)
这种方法声明的属性在C++和QML中都可能被更改,当在 C++中改变该参数值时,发射 valueChanged 信号来通知 qml 。在 qml 中也可以对test进行赋值,触发 C++中的 settest 函数,来实现相关属性的更改。
方法声明
方法声明只需要我们在函数定义前面添加 Q_INVOKABLE 即可。
如:Q_INVOKABLE void test(void);
本例声明了下面两个属性,test1和test2在C++和QML中都可能被更改,当值更改时,触发valueChanged信号
在QML中将输入框textEdit显示的内容设置为_SimpleTest.test1
,_SimpleTest.test1
对应C++中的:
QString test1 ()
{
return _test1;
}
_test1定义如下,默认值为“A”,所以框中默认显示A
QString _test1="A";
在QML中通过_SimpleTest.test1
对属性进行赋值,点击按钮后将test1赋值为“C”
_SimpleTest.test1
调用了C++的setTest1
方法,在该方法中将形参(也就是“C”)赋值给_test1,同时触发valueChanged()信号,通知QML相关的属性已发生改变,来更新相关的显示。
void SimpleTest::setTest1(QString test)
{
_test1=test;
qDebug()<<test;
emit valueChanged();
}
所以本例中在点击按钮后,输入框textEdit显示的值将从“A”变为“C”
以单例形式访问:
上面的步骤完成后,在qml中可以直接使用
4、信号与槽
信号(Signal)就是在特定情况下被发射的事件(如上一节的valueChanged()),槽函数相当于回调函数,在触发特定的信号后执行。
槽函数的声明:
C++中连接信号与槽
一般在构造函数中连接。
connect的参数的含义如下:
connect(
const QObject *sender, //信号发送者
const char *signal, //发送的信号
const QObject *receiver, //信号接收者
const char *method, //表示与信号连接的方式的字符串,可以是槽或信号
Qt::ConnectionType type = Qt::AutoConnection //连接方式,默认自动连接
)
本例中信号是valueChanged(),槽函数是_test()。
槽函数的实现如下:
void SimpleTest::_test()
{
qDebug()<<"in C++ slot";
emit _testChanged();
}
在槽函数中发射了_testChanged()信号。
QML中连接信号与槽
QML通过Connections类型连接信号与槽函数。本例如下:
Connections分为两部分:一个是target属性,表示发出信号的对象。另一个是对应信号的槽函数。
使用示例如下:
Connections {
target: targetA;
function onAsignal1() {
// 信号处理槽函数
}
}
本例中信号发出的对象来自_SimpleTest,具体的信号为_testChanged(),在槽函数中将
_SimpleTest.test2设置为“c”
也就是说,点击按钮后,会触发valueChanged()信号,进入到C++的_test()槽函数中,发射_testChanged()信号,进入到QML的on_testChanged,将test2设置为“c”。
5、测试
编译QGC,进入下面的页面。
点击“发送”按钮,原来的A和a会变成C和c。