如何添加跟隨面板顯示關鍵引數
- 一. 要實作的目標
- 二. 代碼分析與修改
- 1. 飛行地圖檔案的分析與修改
- 2. 代理檔案中資料源
- 3. 代理檔案中顯示形式
所有的熱愛都要不遺余力,真正喜歡它便給它更高的優先級,和更多的時間吧!
關于QGC地面站其它文章請點擊這里: QGC地面站
一. 要實作的目標
當飛機在地圖上飛行時,實作飛機圖示實時跟隨一個引數小面板,讓用戶對關鍵資訊一目了然, 此引數小面板設定為半透明,可實時跟隨飛機圖示移動,顯示內容包括電池剩余百分比、電池電壓、飛行模式、地速、空速、爬升速度、相對高度、飛行距離等關鍵引數,如下gif:

源檔案在最下面…
二. 代碼分析與修改
1. 飛行地圖檔案的分析與修改
代碼如下:(FlightDisplayViewMap.qml):
// Add the vehicles to the map 244行
MapItemView { //標記1
model: QGroundControl.multiVehicleManager.vehicles //標記2
delegate: VehicleMapItem { //標記3
vehicle: object
coordinate: object.coordinate //標記4
map: flightMap
size: mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight
//z: QGroundControl.zOrderVehicles //總修改1-1
}
z: QGroundControl.zOrderTopMost //總修改1-2
}
參考:QT Creator 幫助中搜 “MapItemView”,MapQuickItem
● 標記1:MapItemView是用來構成Map的一部分的,它資料主要是源自model(ListModel、RouteModel等),和ListView 相似 ,也是mode-delegate模型, 僅僅不同于MapItemView的代理Delegate需要為地圖控制元件,即位置設定為經緯度坐標,ListView的Delegate控制元件為桌面控制元件,位置設定為螢屏位置, MapItemView型別只有在包含在Map中時才有意義,它不能獨立存在,
● 標記2:model:提供資料給委托定義的mapItem(VehicleMapItem),由它提供的資訊(飛行模式、地速、空速、爬升速度、相對高度、飛行距離)作為Map ItemView的輸入,下面再具體講解,記住model 僅支持 “QAbstractItemModel” 的基礎模型,
顯然 “QGroundControl.multiVehicleManager.vehicles” 是 QAbstractItemModel 型別的,如下:
// src\Vehicle\MultiVehicleManager.h:100
QmlObjectListModel* vehicles(void) { return &_vehicles; }
● 標記3:delegate:定義了模型中的每個項改如何顯示, 要求 delegate 必須為組件,且包含一個map Item, “MapQuickItem”型別的居多,
● 標記4:coordinate:定位坐標,為什么能動態跟隨,此為最關鍵的屬性,它在C++ vehiclel 類中會實時更新,(NOTIFY修飾的屬性,下文會講到)
coordinate是“MapQuickItem”的一個屬性, 此屬性保存MapQuickItem的錨點坐標,在地圖顯示時,由anchorPoint指定的sourceItem上的點與此坐標保持會一致,
在此MapItemView中,object 對應的就是 vehicles ,委托了VehicleMapItem來實作,VehicleMapItem為MapQuickItem型別的,MapQuickItem的sourceItem指定了一個Item來如何顯示,該Item就是9行3列的關鍵引數的顯示資訊,
● 修改1: 此檔案中僅修改一處“z” 屬性,是為了讓面板在頂層顯示,記得放在“MapItemView”的屬性下,不然不會生效,這很關鍵
接下來讓我再看看代理中的檔案吧!
2. 代理檔案中資料源
上文提到 model,由它提供的飛行模式、地速、空速、爬升速度、相對高度、飛行距離的,
flightMode、roll、groundSpeed都是在“VehicleMapItem”中定義的變數, object.flightMode、object.roll.rawValue、 object.groundSpeed.rawValue來自于“vehicles”,那么再看下 C++中的Vehicle吧
● 修改2: 在檔案頭增加如下屬性:
//總修改2: (object = vehicle = QGroundControl.multiVehicleManager.vehicles)
property string flightMode: vehicle.flightMode;
property real roll: vehicle.roll.rawValue;
property real groundSpeed: vehicle.groundSpeed.rawValue;
property real airSpeed: vehicle.airSpeed.rawValue;
property real climbRate: vehicle.climbRate.rawValue;
property real altitudeRelative: vehicle.altitudeRelative.rawValue;
property real flightDistance: vehicle.flightDistance.rawValue;
property real distanceToHome: object.distanceToHome.rawValue;
property real batteryPercentRemain: object.battery.percentRemaining.value
property real batteryVoltage: object.battery.voltage.value;
object = vehicle = QGroundControl.multiVehicleManager.vehicles ,讓我們在看看vehicle類…
● C++中的Vehicle類的分析,
要在QML實時顯示,那么必須是“NOTIFY”修飾的信號,它給屬性關聯一個信號,當屬性的值發生變化時就會觸發該信號,比下flightMode屬性,
Q_PROPERTY(QString flightMode READ flightMode WRITE setFlightMode NOTIFY flightModeChanged)
C++和QML之間不懂如何互動的可以點擊這里:Qt Quick Qml 之QML與C++ 混合編程學習
當我們在 C++中改變該引數值時,發射 flightModeChanged 信號, 來通知 qml 相關的屬性有更改,進而實作相關的狀態更改,沒有“NOTIFY”修飾的,不會實時觸發,也不會動態更新了,
但是是不是發現在Vehicle類中,一些關鍵的屬性并沒有使用NOTIFY ?
如下:
Fact* roll () { return &_rollFact; }
Fact* rollRate () { return &_rollRateFact; }
Fact* pitchRate () { return &_pitchRateFact; }
Fact* yawRate () { return &_yawRateFact; }
Fact* airSpeed () { return &_airSpeedFact; }
Fact* groundSpeed () { return &_groundSpeedFact; }
Fact* climbRate () { return &_climbRateFact; }
仔細分析Fact類:
class Fact : public QObject
{
Q_OBJECT
...
Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT)
Q_PROPERTY(QString units READ cookedUnits CONSTANT)
Q_PROPERTY(QVariant value READ cookedValue WRITE setCookedValue NOTIFY valueChanged)
Q_PROPERTY(QVariant rawValue READ rawValue WRITE setRawValue NOTIFY rawValueChanged)
}
發現“rawValue ”也用“NOTIFY”修飾了,所以問題就很簡單了,直接去到 “rawValue” 就好
...
property string flightMode: vehicle.flightMode;
property real roll: vehicle.roll.rawValue;
property real groundSpeed: vehicle.groundSpeed.rawValue;
property real airSpeed: vehicle.airSpeed.rawValue;
property real climbRate: vehicle.climbRate.rawValue;
...
3. 代理檔案中顯示形式
● 修改3: 在MapQuickItem中的“ sourceItem: Item "中最后增加矩形框:
Rectangle {
id: cchVehicleStatusView;
anchors.bottom: vehicleIcon.top;
anchors.bottomMargin: 4
anchors.horizontalCenter: vehicleIcon.horizontalCenter;
color: "#DDDDFF"
radius: 10
width: buttonColumn.implicitWidth * 1.1
height: buttonColumn.implicitHeight * 1.1
opacity : 0.8;
border.color: "black"
border.width: 2
Column {
id: buttonColumn
width: statusNameRepeater.implicitWidth
height: statusNameRepeater.implicitHeight
anchors.top: parent.top
anchors.topMargin: 6
anchors.left: parent.left
anchors.leftMargin: 6
spacing: ScreenTools.defaultFontPixelHeight / 2
Repeater {
id: statusNameRepeater
model: 9
property var statusNames: [ "電池剩余百分比: ", "電池電壓: ", qsTr("飛行模式:"), qsTr("地速: "), qsTr("空速: "), qsTr("爬升速度: "), qsTr("相對高度: "), qsTr("飛行距離: "),"到home點距離: "]
property var statusValues: [batteryPercentRemain, batteryVoltage, flightMode, groundSpeed.toFixed(2), airSpeed.toFixed(2), climbRate.toFixed(2), altitudeRelative.toFixed(2), flightDistance.toFixed(2), distanceToHome.toFixed(2)]
property var statusUnits: ["%", "v", "", "(m/s)", "(m/s)", "(m/s)", "(m)", "(m)", "(m)"]
Row{
id: _row
QGCLabel {
color: "#424200"
horizontalAlignment: Text.AlignHCenter
font.pointSize: ScreenTools.mediumFontPointSize * 1.0
text: statusNameRepeater.statusNames[index]
font.bold: true
}
QGCLabel {
color: "#336666"
horizontalAlignment: Text.AlignHCenter
font.pointSize: ScreenTools.mediumFontPointSize *1.0
text: statusNameRepeater.statusValues[index] + statusNameRepeater.statusUnits[index]
font.bold: true
}
}
}
}
}
這個Column和Row的嵌套布局的詳細解釋,可以看我的 QT Quick QML 布局——定位置布局(Row、Column、Grid、Flow和Repeater) 總結, 這里不再介紹,
如下綠色框中:

有其他想法的,可以在飛行視圖中,增加一個控制元件,來配置矩形框是否顯示;還可以增加一個定時器讓變化的資料高亮顯示;有UI美工支持的還可以弄個炫酷的皮膚,為什么要這樣呢?
沒有別的原因,一切為狂拽酷炫,哈哈! 具體就不一一介紹啦,自己開動小腦袋瓜子哦~
關于QGC地面站其它文章請點擊這里: QGC地面站
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/231475.html
標籤:其他
上一篇:vulnhub potato
