2020-10-29 21:28:00 +08:00
|
|
|
#include "MAVLinkInspector.h"
|
2020-06-11 17:32:58 +08:00
|
|
|
#include "ui_MAVLinkInspector.h"
|
|
|
|
|
#include <QList>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
const float MAVLinkInspector::updateHzLowpass = 0.2f;
|
|
|
|
|
const unsigned int MAVLinkInspector::updateInterval = 1000U;
|
|
|
|
|
|
|
|
|
|
MAVLinkInspector::MAVLinkInspector(const QString& title, QAction* action,QWidget *parent) :
|
|
|
|
|
selectedSystemID(0),
|
|
|
|
|
selectedComponentID(0),
|
|
|
|
|
ui(new Ui::MAVLinkInspector)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(action)
|
|
|
|
|
Q_UNUSED(parent)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
|
|
|
|
|
setWindowTitle(title);
|
|
|
|
|
|
|
|
|
|
// Make sure "All" is an option for both the system and components
|
|
|
|
|
//ui->systemComboBox->addItem(tr("All"), 0);
|
|
|
|
|
//ui->componentComboBox->addItem(tr("All"), 0);
|
|
|
|
|
|
|
|
|
|
// Set up the column headers for the message listing
|
|
|
|
|
QStringList header;
|
|
|
|
|
header << tr("Name");
|
|
|
|
|
header << tr("Value");
|
|
|
|
|
header << tr("Type");
|
|
|
|
|
ui->treeWidget->setHeaderLabels(header);
|
|
|
|
|
|
2020-10-29 21:28:00 +08:00
|
|
|
ui->treeWidget->header()->resizeSection(0,650);
|
|
|
|
|
ui->treeWidget->header()->resizeSection(1,300);
|
2020-06-11 17:32:58 +08:00
|
|
|
ui->treeWidget->header()->resizeSection(2,50);
|
|
|
|
|
|
|
|
|
|
ui->treeWidget->header()->setStretchLastSection(true);
|
|
|
|
|
|
2020-11-19 15:37:11 +08:00
|
|
|
ui->treeWidget->setHeaderHidden(false);
|
|
|
|
|
|
2020-06-11 17:32:58 +08:00
|
|
|
connect(ui->clearButton, &QPushButton::clicked, this, &MAVLinkInspector::clearView);
|
|
|
|
|
|
|
|
|
|
// Attach the UI's refresh rate to a timer.
|
|
|
|
|
connect(&updateTimer, &QTimer::timeout, this, &MAVLinkInspector::refreshView);
|
|
|
|
|
updateTimer.start(updateInterval);
|
|
|
|
|
|
|
|
|
|
//loadSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::_vehicleAdded(quint32 id)
|
|
|
|
|
{
|
|
|
|
|
ui->pushButton_system->setText(tr("Vehicle %1").arg(id));
|
|
|
|
|
|
|
|
|
|
// Add a tree for a new UAS
|
|
|
|
|
addUAStoTree(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::selectDropDownMenuSystem(int dropdownid)
|
|
|
|
|
{
|
|
|
|
|
//selectedSystemID = ui->systemComboBox->itemData(dropdownid).toInt();
|
|
|
|
|
rebuildComponentList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::selectDropDownMenuComponent(int dropdownid)
|
|
|
|
|
{
|
|
|
|
|
//selectedComponentID = ui->componentComboBox->itemData(dropdownid).toInt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::rebuildComponentList()
|
|
|
|
|
{
|
|
|
|
|
//ui->componentComboBox->clear();
|
|
|
|
|
components.clear();
|
|
|
|
|
|
|
|
|
|
//ui->componentComboBox->addItem(tr("All"), 0);
|
|
|
|
|
|
|
|
|
|
// Fill
|
|
|
|
|
/*
|
|
|
|
|
Vehicle* vehicle = qgcApp()->toolbox()->multiVehicleManager()->getVehicleById(selectedSystemID);
|
|
|
|
|
if (vehicle)
|
|
|
|
|
{
|
|
|
|
|
UASInterface* uas = vehicle->uas();
|
|
|
|
|
QMap<int, QString> components = uas->getComponents();
|
|
|
|
|
foreach (int id, components.keys())
|
|
|
|
|
{
|
|
|
|
|
QString name = components.value(id);
|
|
|
|
|
ui->componentComboBox->addItem(name, id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::on_pushButton_system_clicked()
|
|
|
|
|
{
|
2020-08-01 10:53:17 +08:00
|
|
|
ui->pushButton_system->hide();
|
|
|
|
|
ui->clearButton->hide();
|
|
|
|
|
|
|
|
|
|
if(!scope)
|
|
|
|
|
{
|
|
|
|
|
scope = new Scope(this);
|
|
|
|
|
|
|
|
|
|
|
2020-08-11 16:48:15 +08:00
|
|
|
connect(scope,SIGNAL(willclose()),
|
2020-08-01 10:53:17 +08:00
|
|
|
this,SLOT(ScopeClose()));
|
|
|
|
|
|
|
|
|
|
connect(scope,SIGNAL(clearall()),
|
|
|
|
|
this,SLOT(ScopeClearall()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui->gridLayout->addWidget(scope,0,0,1,1);
|
|
|
|
|
scope->show();
|
|
|
|
|
}
|
2020-08-01 13:10:50 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
scope->show();
|
|
|
|
|
}
|
2020-08-01 10:53:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::ScopeClose(void)//可能有点问题
|
|
|
|
|
{
|
|
|
|
|
ui->pushButton_system->show();
|
|
|
|
|
ui->clearButton->show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::ScopeClearall(void)
|
|
|
|
|
{
|
|
|
|
|
clearView();
|
|
|
|
|
//qDebug() << "ScopeClearall";
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::addComponent(int uas, int component, const QString& name)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(component);
|
|
|
|
|
Q_UNUSED(name);
|
|
|
|
|
|
|
|
|
|
if (uas != selectedSystemID) return;
|
|
|
|
|
|
|
|
|
|
rebuildComponentList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reset the view. This entails clearing all data structures and resetting data from already-
|
|
|
|
|
* received messages.
|
|
|
|
|
*/
|
|
|
|
|
void MAVLinkInspector::clearView()
|
|
|
|
|
{
|
|
|
|
|
QMap<int, mavlink_message_t* >::iterator ite;
|
|
|
|
|
for(ite=uasMessageStorage.begin(); ite!=uasMessageStorage.end();++ite)
|
|
|
|
|
{
|
|
|
|
|
delete ite.value();
|
|
|
|
|
ite.value() = nullptr;
|
|
|
|
|
}
|
|
|
|
|
uasMessageStorage.clear();
|
|
|
|
|
|
|
|
|
|
QMap<int, QMap<int, QTreeWidgetItem*>* >::iterator iteMsg;
|
|
|
|
|
for (iteMsg=uasMsgTreeItems.begin(); iteMsg!=uasMsgTreeItems.end();++iteMsg)
|
|
|
|
|
{
|
|
|
|
|
QMap<int, QTreeWidgetItem*>* msgTreeItems = iteMsg.value();
|
|
|
|
|
|
|
|
|
|
QList<int> groupKeys = msgTreeItems->uniqueKeys();
|
|
|
|
|
QList<int>::iterator listKeys;
|
|
|
|
|
for (listKeys=groupKeys.begin();listKeys!=groupKeys.end();++listKeys)
|
|
|
|
|
{
|
|
|
|
|
delete msgTreeItems->take(*listKeys);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
uasMsgTreeItems.clear();
|
|
|
|
|
|
|
|
|
|
QMap<int, QTreeWidgetItem* >::iterator iteTree;
|
|
|
|
|
for(iteTree=uasTreeWidgetItems.begin(); iteTree!=uasTreeWidgetItems.end();++iteTree)
|
|
|
|
|
{
|
|
|
|
|
delete iteTree.value();
|
|
|
|
|
iteTree.value() = NULL;
|
|
|
|
|
}
|
|
|
|
|
uasTreeWidgetItems.clear();
|
|
|
|
|
|
|
|
|
|
QMap<int, QMap<int, float>* >::iterator iteHz;
|
|
|
|
|
for (iteHz=uasMessageHz.begin(); iteHz!=uasMessageHz.end();++iteHz)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
iteHz.value()->clear();
|
|
|
|
|
delete iteHz.value();
|
|
|
|
|
iteHz.value() = NULL;
|
|
|
|
|
}
|
|
|
|
|
uasMessageHz.clear();
|
|
|
|
|
|
|
|
|
|
QMap<int, QMap<int, unsigned int>* >::iterator iteCount;
|
|
|
|
|
for(iteCount=uasMessageCount.begin(); iteCount!=uasMessageCount.end();++iteCount)
|
|
|
|
|
{
|
|
|
|
|
iteCount.value()->clear();
|
|
|
|
|
delete iteCount.value();
|
|
|
|
|
iteCount.value() = NULL;
|
|
|
|
|
}
|
|
|
|
|
uasMessageCount.clear();
|
|
|
|
|
|
|
|
|
|
QMap<int, QMap<int, quint64>* >::iterator iteLast;
|
|
|
|
|
for(iteLast=uasLastMessageUpdate.begin(); iteLast!=uasLastMessageUpdate.end();++iteLast)
|
|
|
|
|
{
|
|
|
|
|
iteLast.value()->clear();
|
|
|
|
|
delete iteLast.value();
|
|
|
|
|
iteLast.value() = NULL;
|
|
|
|
|
}
|
|
|
|
|
uasLastMessageUpdate.clear();
|
|
|
|
|
|
|
|
|
|
onboardMessageInterval.clear();
|
|
|
|
|
|
|
|
|
|
ui->treeWidget->clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::refreshView()
|
|
|
|
|
{
|
|
|
|
|
QMap<int, mavlink_message_t* >::const_iterator ite;
|
|
|
|
|
|
|
|
|
|
for(ite=uasMessageStorage.constBegin(); ite!=uasMessageStorage.constEnd();++ite)
|
|
|
|
|
{
|
|
|
|
|
mavlink_message_t* msg = ite.value();
|
|
|
|
|
const mavlink_message_info_t* msgInfo = mavlink_get_message_info(msg);
|
|
|
|
|
|
|
|
|
|
if (!msgInfo) {
|
|
|
|
|
qWarning() << QStringLiteral("MAVLinkInspector::refreshView NULL msgInfo msgid(%1)").arg(msg->msgid);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore NULL values
|
|
|
|
|
if (msg->msgid == 0xFF) continue;
|
|
|
|
|
|
|
|
|
|
// Update the message frenquency
|
|
|
|
|
|
|
|
|
|
// Get the previous frequency for low-pass filtering
|
|
|
|
|
float msgHz = 0.0f;
|
|
|
|
|
QMap<int, QMap<int, float>* >::const_iterator iteHz = uasMessageHz.find(msg->sysid);
|
|
|
|
|
QMap<int, float>* uasMsgHz = iteHz.value();
|
|
|
|
|
|
|
|
|
|
while((iteHz != uasMessageHz.end()) && (iteHz.key() == msg->sysid))
|
|
|
|
|
{
|
|
|
|
|
if(iteHz.value()->contains(msg->msgid))
|
|
|
|
|
{
|
|
|
|
|
uasMsgHz = iteHz.value();
|
|
|
|
|
msgHz = iteHz.value()->value(msg->msgid);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++iteHz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the number of message received
|
|
|
|
|
float msgCount = 0;
|
|
|
|
|
QMap<int, QMap<int, unsigned int> * >::const_iterator iter = uasMessageCount.find(msg->sysid);
|
|
|
|
|
QMap<int, unsigned int>* uasMsgCount = iter.value();
|
|
|
|
|
|
|
|
|
|
while((iter != uasMessageCount.end()) && (iter.key()==msg->sysid))
|
|
|
|
|
{
|
|
|
|
|
if(iter.value()->contains(msg->msgid))
|
|
|
|
|
{
|
|
|
|
|
msgCount = (float) iter.value()->value(msg->msgid);
|
|
|
|
|
uasMsgCount = iter.value();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++iter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compute the new low-pass filtered frequency and update the message count
|
|
|
|
|
msgHz = (1.0f-updateHzLowpass)* msgHz + updateHzLowpass*msgCount/((float)updateInterval/1000.0f);
|
|
|
|
|
uasMsgHz->insert(msg->msgid,msgHz);
|
|
|
|
|
uasMsgCount->insert(msg->msgid,(unsigned int) 0);
|
|
|
|
|
|
|
|
|
|
// Update the tree view
|
|
|
|
|
QString messageName("%1 (%2 Hz, #%3)");
|
|
|
|
|
messageName = messageName.arg(msgInfo->name).arg(msgHz, 3, 'f', 1).arg(msg->msgid);
|
|
|
|
|
|
|
|
|
|
addUAStoTree(msg->sysid);
|
|
|
|
|
|
|
|
|
|
// Look for the tree for the UAS sysid
|
|
|
|
|
QMap<int, QTreeWidgetItem*>* msgTreeItems = uasMsgTreeItems.value(msg->sysid);
|
|
|
|
|
if (!msgTreeItems)
|
|
|
|
|
{
|
|
|
|
|
// The UAS tree has not been created yet, no update
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add the message with msgid to the tree if not done yet
|
|
|
|
|
if(!msgTreeItems->contains(msg->msgid))
|
|
|
|
|
{
|
|
|
|
|
QStringList fields;
|
|
|
|
|
fields << messageName;
|
|
|
|
|
QTreeWidgetItem* widget = new QTreeWidgetItem();
|
|
|
|
|
for (unsigned int i = 0; i < msgInfo->num_fields; ++i)
|
|
|
|
|
{
|
|
|
|
|
QTreeWidgetItem* field = new QTreeWidgetItem();
|
2020-08-01 10:53:17 +08:00
|
|
|
field->setCheckState(0,Qt::Unchecked);
|
|
|
|
|
//widget->setCheckState(0,Qt::PartiallyChecked);
|
2020-06-11 17:32:58 +08:00
|
|
|
widget->addChild(field);
|
|
|
|
|
}
|
|
|
|
|
msgTreeItems->insert(msg->msgid,widget);
|
|
|
|
|
QList<int> groupKeys = msgTreeItems->uniqueKeys();
|
|
|
|
|
int insertIndex = groupKeys.indexOf(msg->msgid);
|
|
|
|
|
uasTreeWidgetItems.value(msg->sysid)->insertChild(insertIndex,widget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the message
|
|
|
|
|
QTreeWidgetItem* message = msgTreeItems->value(msg->msgid);
|
|
|
|
|
if(message)
|
|
|
|
|
{
|
|
|
|
|
message->setFirstColumnSpanned(true);
|
|
|
|
|
message->setData(0, Qt::DisplayRole, QVariant(messageName));
|
|
|
|
|
for (unsigned int i = 0; i < msgInfo->num_fields; ++i)
|
|
|
|
|
{
|
|
|
|
|
updateField(msg, msgInfo, i, message->child(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::addUAStoTree(int sysId)
|
|
|
|
|
{
|
|
|
|
|
if(!uasTreeWidgetItems.contains(sysId))
|
|
|
|
|
{
|
|
|
|
|
if (1)//vehicle)
|
|
|
|
|
{
|
|
|
|
|
//UASInterface* uas = vehicle->uas();
|
|
|
|
|
QStringList idstring;
|
2020-07-27 18:02:09 +08:00
|
|
|
idstring << QString(tr("Vehicle %1").arg(sysId));//uas->getUASID());
|
2020-06-11 17:32:58 +08:00
|
|
|
QTreeWidgetItem* uasWidget = new QTreeWidgetItem(idstring);
|
|
|
|
|
uasWidget->setFirstColumnSpanned(true);
|
|
|
|
|
uasTreeWidgetItems.insert(sysId,uasWidget);
|
|
|
|
|
ui->treeWidget->addTopLevelItem(uasWidget);
|
|
|
|
|
uasMsgTreeItems.insert(sysId,new QMap<int, QTreeWidgetItem*>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::receiveMessage(mavlink_message_t message)
|
|
|
|
|
{
|
|
|
|
|
//Q_UNUSED(link);
|
|
|
|
|
|
|
|
|
|
quint64 receiveTime;
|
|
|
|
|
|
|
|
|
|
if (selectedSystemID != 0 && selectedSystemID != message.sysid) return;
|
|
|
|
|
if (selectedComponentID != 0 && selectedComponentID != message.compid) return;
|
|
|
|
|
|
|
|
|
|
// Create dynamically an array to store the messages for each UAS
|
|
|
|
|
if (!uasMessageStorage.contains(message.sysid))
|
|
|
|
|
{
|
|
|
|
|
mavlink_message_t* msg = new mavlink_message_t;
|
|
|
|
|
*msg = message;
|
|
|
|
|
uasMessageStorage.insertMulti(message.sysid,msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool msgFound = false;
|
|
|
|
|
QMap<int, mavlink_message_t* >::const_iterator iteMsg = uasMessageStorage.find(message.sysid);
|
|
|
|
|
mavlink_message_t* uasMessage = iteMsg.value();
|
|
|
|
|
while((iteMsg != uasMessageStorage.end()) && (iteMsg.key() == message.sysid))
|
|
|
|
|
{
|
|
|
|
|
if (iteMsg.value()->msgid == message.msgid)
|
|
|
|
|
{
|
|
|
|
|
msgFound = true;
|
|
|
|
|
uasMessage = iteMsg.value();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++iteMsg;
|
|
|
|
|
}
|
|
|
|
|
if (!msgFound)
|
|
|
|
|
{
|
|
|
|
|
mavlink_message_t* msgIdMessage = new mavlink_message_t;
|
|
|
|
|
*msgIdMessage = message;
|
|
|
|
|
uasMessageStorage.insertMulti(message.sysid,msgIdMessage);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*uasMessage = message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Looking if this message has already been received once
|
|
|
|
|
msgFound = false;
|
|
|
|
|
QMap<int, QMap<int, quint64>* >::const_iterator ite = uasLastMessageUpdate.find(message.sysid);
|
|
|
|
|
QMap<int, quint64>* lastMsgUpdate = ite.value();
|
|
|
|
|
while((ite != uasLastMessageUpdate.end()) && (ite.key() == message.sysid))
|
|
|
|
|
{
|
|
|
|
|
if(ite.value()->contains(message.msgid))
|
|
|
|
|
{
|
|
|
|
|
msgFound = true;
|
|
|
|
|
|
|
|
|
|
// Point to the found message
|
|
|
|
|
lastMsgUpdate = ite.value();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++ite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//输入时间
|
|
|
|
|
receiveTime = QDateTime::currentMSecsSinceEpoch();//0;//QGC::groundTimeMilliseconds();
|
|
|
|
|
|
|
|
|
|
// If the message doesn't exist, create a map for the frequency, message count and time of reception
|
|
|
|
|
if(!msgFound)
|
|
|
|
|
{
|
|
|
|
|
// Create a map for the message frequency
|
|
|
|
|
QMap<int, float>* messageHz = new QMap<int,float>;
|
|
|
|
|
messageHz->insert(message.msgid,0.0f);
|
|
|
|
|
uasMessageHz.insertMulti(message.sysid,messageHz);
|
|
|
|
|
|
|
|
|
|
// Create a map for the message count
|
|
|
|
|
QMap<int, unsigned int>* messagesCount = new QMap<int, unsigned int>;
|
|
|
|
|
messagesCount->insert(message.msgid,0);
|
|
|
|
|
uasMessageCount.insertMulti(message.sysid,messagesCount);
|
|
|
|
|
|
|
|
|
|
// Create a map for the time of reception of the message
|
|
|
|
|
QMap<int, quint64>* lastMessage = new QMap<int, quint64>;
|
|
|
|
|
lastMessage->insert(message.msgid,receiveTime);
|
|
|
|
|
uasLastMessageUpdate.insertMulti(message.sysid,lastMessage);
|
|
|
|
|
|
|
|
|
|
// Point to the created message
|
|
|
|
|
lastMsgUpdate = lastMessage;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// The message has been found/created
|
|
|
|
|
if ((lastMsgUpdate->contains(message.msgid))&&(uasMessageCount.contains(message.sysid)))
|
|
|
|
|
{
|
|
|
|
|
// Looking for and updating the message count
|
|
|
|
|
unsigned int count = 0;
|
|
|
|
|
QMap<int, QMap<int, unsigned int>* >::const_iterator iter = uasMessageCount.find(message.sysid);
|
|
|
|
|
QMap<int, unsigned int> * uasMsgCount = iter.value();
|
|
|
|
|
while((iter != uasMessageCount.end()) && (iter.key() == message.sysid))
|
|
|
|
|
{
|
|
|
|
|
if(iter.value()->contains(message.msgid))
|
|
|
|
|
{
|
|
|
|
|
uasMsgCount = iter.value();
|
|
|
|
|
count = uasMsgCount->value(message.msgid,0);
|
|
|
|
|
uasMsgCount->insert(message.msgid,count+1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++iter;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lastMsgUpdate->insert(message.msgid,receiveTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (selectedSystemID == 0 || selectedComponentID == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (message.msgid)
|
|
|
|
|
{
|
|
|
|
|
case MAVLINK_MSG_ID_DATA_STREAM:
|
|
|
|
|
{
|
|
|
|
|
mavlink_data_stream_t stream;
|
|
|
|
|
mavlink_msg_data_stream_decode(&message, &stream);
|
|
|
|
|
onboardMessageInterval.insert(stream.stream_id, stream.message_rate);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MAVLinkInspector::~MAVLinkInspector()
|
|
|
|
|
{
|
|
|
|
|
clearView();
|
|
|
|
|
delete ui;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::updateField(mavlink_message_t* msg, const mavlink_message_info_t* msgInfo, int fieldid, QTreeWidgetItem* item)
|
|
|
|
|
{
|
|
|
|
|
// Add field tree widget item
|
|
|
|
|
item->setData(0, Qt::DisplayRole, QVariant(msgInfo->fields[fieldid].name));
|
|
|
|
|
|
|
|
|
|
bool msgFound = false;
|
|
|
|
|
QMap<int, mavlink_message_t* >::const_iterator iteMsg = uasMessageStorage.find(msg->sysid);
|
|
|
|
|
mavlink_message_t* uasMessage = iteMsg.value();
|
|
|
|
|
while((iteMsg != uasMessageStorage.end()) && (iteMsg.key() == msg->sysid))
|
|
|
|
|
{
|
|
|
|
|
if (iteMsg.value()->msgid == msg->msgid)
|
|
|
|
|
{
|
|
|
|
|
msgFound = true;
|
|
|
|
|
uasMessage = iteMsg.value();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++iteMsg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!msgFound)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-13 12:28:38 +08:00
|
|
|
|
2020-09-23 14:40:11 +08:00
|
|
|
#ifdef MAVLINK_VERSION_2
|
2020-06-11 17:32:58 +08:00
|
|
|
uint8_t* m = (uint8_t*)&uasMessage->payload64[0];
|
2020-09-23 14:40:11 +08:00
|
|
|
#else
|
|
|
|
|
uint8_t* m = (uint8_t*)&uasMessage->payload[0];
|
|
|
|
|
#endif
|
2020-06-11 17:32:58 +08:00
|
|
|
|
|
|
|
|
switch (msgInfo->fields[fieldid].type)
|
|
|
|
|
{
|
|
|
|
|
case MAVLINK_TYPE_CHAR:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
char* str = (char*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
str[msgInfo->fields[fieldid].array_length-1] = '\0';
|
|
|
|
|
QString string(str);
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "char");
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single char
|
|
|
|
|
char b = *((char*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("char[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, b);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_UINT8_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* nums = m+msgInfo->fields[fieldid].wire_offset;
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("uint8_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
2020-10-30 15:36:25 +08:00
|
|
|
uint8_t n = *(m+msgInfo->fields[fieldid].wire_offset);
|
2020-06-11 17:32:58 +08:00
|
|
|
item->setData(2, Qt::DisplayRole, "uint8_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_INT8_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
int8_t* nums = (int8_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("int8_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
int8_t n = *((int8_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "int8_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_UINT16_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
uint16_t* nums = (uint16_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("uint16_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
uint16_t n = *((uint16_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "uint16_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_INT16_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
int16_t* nums = (int16_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("int16_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
int16_t n = *((int16_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "int16_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_UINT32_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
uint32_t* nums = (uint32_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("uint32_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
float n = *((uint32_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "uint32_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_INT32_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
int32_t* nums = (int32_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("int32_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
int32_t n = *((int32_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "int32_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_FLOAT:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
float* nums = (float*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("float[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
2020-10-30 15:36:25 +08:00
|
|
|
float n = *((float*)(m+msgInfo->fields[fieldid].wire_offset));
|
2020-06-11 17:32:58 +08:00
|
|
|
item->setData(2, Qt::DisplayRole, "float");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_DOUBLE:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
double* nums = (double*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("double[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
2020-10-30 15:36:25 +08:00
|
|
|
double n = *((double*)(m+msgInfo->fields[fieldid].wire_offset));
|
2020-06-11 17:32:58 +08:00
|
|
|
item->setData(2, Qt::DisplayRole, "double");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number(n));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_UINT64_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
uint64_t* nums = (uint64_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("uint64_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
uint64_t n = *((uint64_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "uint64_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number((quint64)n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MAVLINK_TYPE_INT64_T:
|
|
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
int64_t* nums = (int64_t*)(m+msgInfo->fields[fieldid].wire_offset);
|
|
|
|
|
// Enforce null termination
|
|
|
|
|
QString tmp("%1, ");
|
|
|
|
|
QString string;
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
string += tmp.arg(nums[j]);
|
|
|
|
|
}
|
|
|
|
|
item->setData(2, Qt::DisplayRole, QString("int64_t[%1]").arg(msgInfo->fields[fieldid].array_length));
|
|
|
|
|
item->setData(1, Qt::DisplayRole, string);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Single value
|
|
|
|
|
int64_t n = *((int64_t*)(m+msgInfo->fields[fieldid].wire_offset));
|
|
|
|
|
item->setData(2, Qt::DisplayRole, "int64_t");
|
2020-10-30 15:36:25 +08:00
|
|
|
item->setData(1, Qt::DisplayRole, QString::number((qint64)n,'f',0));
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-08-01 10:53:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if(item->checkState(0) == Qt::Checked)
|
|
|
|
|
{
|
2020-10-30 15:36:25 +08:00
|
|
|
if (msgInfo->fields[fieldid].array_length > 0)
|
|
|
|
|
{
|
|
|
|
|
QString str = item->data(1,Qt::DisplayRole).toString();
|
|
|
|
|
|
|
|
|
|
QStringList sections = str.split(QRegExp("[,*/^]")); //把每一个块装进一个QStringList中
|
|
|
|
|
|
|
|
|
|
for (unsigned int j = 0; j < msgInfo->fields[fieldid].array_length; ++j)
|
|
|
|
|
{
|
|
|
|
|
if(scope)
|
|
|
|
|
{
|
|
|
|
|
scope->chartView->setSerieData(QString::number(msg->sysid) + "." + item->data(0,Qt::DisplayRole).toString() + "[" + QString::number(j) + "]",sections[j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2020-08-01 13:10:50 +08:00
|
|
|
{
|
|
|
|
|
if(scope)
|
|
|
|
|
{
|
2020-08-13 16:36:49 +08:00
|
|
|
scope->chartView->setSerieData(QString::number(msg->sysid) + "." + item->data(0,Qt::DisplayRole).toString(),item->data(1,Qt::DisplayRole));
|
2020-08-01 13:10:50 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-08-01 10:53:17 +08:00
|
|
|
}
|
2020-06-11 17:32:58 +08:00
|
|
|
}
|
|
|
|
|
|
2020-06-15 18:24:22 +08:00
|
|
|
|
|
|
|
|
void MAVLinkInspector::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
|
|
|
|
|
{
|
|
|
|
|
QString parentdata;
|
|
|
|
|
|
|
|
|
|
if(item->parent())//不是根节点才可以把数据写入框内
|
|
|
|
|
{
|
|
|
|
|
if(item->parent()->parent())
|
|
|
|
|
{
|
|
|
|
|
parentdata = item->parent()->parent()->data(0,Qt::DisplayRole).toString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
parentdata = item->parent()->data(0,Qt::DisplayRole).toString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
parentdata = item->data(0,Qt::DisplayRole).toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ui->pushButton_system->setText(parentdata);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-27 18:02:09 +08:00
|
|
|
|
|
|
|
|
void MAVLinkInspector::on_treeWidget_itemChanged(QTreeWidgetItem *item, int column)
|
|
|
|
|
{
|
2020-08-01 13:10:50 +08:00
|
|
|
QString itemText = item->text(0);
|
2020-07-27 18:02:09 +08:00
|
|
|
if (item->checkState(0) == Qt::Checked)
|
2020-08-01 13:10:50 +08:00
|
|
|
{
|
2020-08-01 10:53:17 +08:00
|
|
|
|
2020-07-27 18:02:09 +08:00
|
|
|
}
|
|
|
|
|
else if (item->checkState(0) == Qt::Unchecked)
|
2020-08-01 13:10:50 +08:00
|
|
|
{
|
|
|
|
|
if(itemText.size() != -1)
|
2020-07-27 18:02:09 +08:00
|
|
|
{
|
2020-08-13 12:28:38 +08:00
|
|
|
//太频繁,可能会出问题
|
2020-08-01 13:10:50 +08:00
|
|
|
if(scope)
|
2020-07-27 18:02:09 +08:00
|
|
|
{
|
2020-08-13 12:28:38 +08:00
|
|
|
if(item->parent()->parent())
|
|
|
|
|
{
|
|
|
|
|
QString str = item->parent()->parent()->text(0);
|
|
|
|
|
str = str.mid(str.indexOf(' ') + 1);
|
2020-08-13 16:36:49 +08:00
|
|
|
scope->chartView->removeSerie(str + "." + item->data(0,Qt::DisplayRole).toString());
|
2020-10-30 15:36:25 +08:00
|
|
|
//qDebug() << str + "." + item->data(0,Qt::DisplayRole).toString();
|
2020-08-13 12:28:38 +08:00
|
|
|
}
|
2020-07-27 18:02:09 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MAVLinkInspector::updateParentItem(QTreeWidgetItem *item)
|
|
|
|
|
{
|
|
|
|
|
QTreeWidgetItem *parent = item->parent();
|
|
|
|
|
if (parent == NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//选中的子节点个数
|
|
|
|
|
int selectedCount = 0;
|
|
|
|
|
int childCount = parent->childCount();
|
|
|
|
|
for (int i = 0; i < childCount; i++)
|
|
|
|
|
{
|
|
|
|
|
QTreeWidgetItem *childItem = parent->child(i);
|
|
|
|
|
if (childItem->checkState(0) == Qt::Checked)
|
|
|
|
|
{
|
|
|
|
|
selectedCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (selectedCount <= 0)
|
|
|
|
|
{
|
|
|
|
|
//未选中状态
|
|
|
|
|
parent->setCheckState(0, Qt::Unchecked);
|
|
|
|
|
}
|
|
|
|
|
else if (selectedCount > 0 && selectedCount < childCount)
|
|
|
|
|
{
|
|
|
|
|
//部分选中状态
|
|
|
|
|
parent->setCheckState(0, Qt::PartiallyChecked);
|
|
|
|
|
}
|
|
|
|
|
else if (selectedCount == childCount)
|
|
|
|
|
{
|
|
|
|
|
//选中状态
|
|
|
|
|
parent->setCheckState(0, Qt::Checked);
|
|
|
|
|
}
|
|
|
|
|
}
|