Обновите MapCircle на QML, используя сигнал из C ++ - PullRequest
1 голос
/ 16 апреля 2020

Я пытаюсь обновить MapCircle в QML по сигналу в C ++, и у меня возникло несколько проблем с этим весь день.

В моем классе у меня есть Q_PROPERTY, который предназначен только для чтения и содержит позиции GPS 4 БПЛА в QVariantList

class GCS: public QObject
{
    Q_PROPERTY(QVariantList getUavPosition READ getUavPosition NOTIFY uavPositionSet)

    public:
      QVariantList getUavPosition() ; 
    signals:
      void uavPositionSet();
     public slots:
       void setUavPosition();
       void triggerPosition();
     private: 
       QVariantList connected_uavs;
       QVector<QGeoCoordinate> uav_positions;         

};

. Затем я определяю функции следующим образом:

void GCS::setUavPosition()
{
  double i = 0.0;

     QGeoCoordinate uav_id;
     uav_id.setLatitude(0.5);
     uav_id.setLongitude(0.5 + i);
     uav_id.setAltitude(5);
     uav_positions.insert(0, uav_id);
     connected_uavs.append( QVariant::fromValue(QGeoCoordinate(uav_positions[0].latitude(), uav_positions[0].longitude())));

      i+=0.15;  
    emit uavPositionSet();

}

 QVariantList GCS::getUavPosition() 
 {
   return connected_uavs;
 }

void GCS::triggerPosition()
{
  setUavPosition();
  ROS_INFO("Pos trig");
}

В своей основной функции я подключаю triggerPosition к таймеру, чтобы периодически обновлять позицию

int main(int argc, char *argv[])
{
     ros::init(argc, argv, "planner");
    QGuiApplication app(argc, argv);

     QQmlApplicationEngine engine;
     QQmlContext* context = engine.rootContext();
     GCS gcs;
     context->setContextProperty("planner", &gcs);    
     engine.load(QUrl(QStringLiteral("qrc:/planner.qml")));

     QTimer *timer = new QTimer();
     timer->setInterval(1000);
     QObject::connect(&gcs, SIGNAL(uavPositionSet()), &gcs, SLOT(setUavPosition()));
     QObject::connect(timer, SIGNAL(timeout()), &gcs, SLOT(triggerPosition()));
     timer->start();

    return app.exec();
}

Однако, когда я запускаю свою программу, есть небольшая задержка, моя mouseArea становится непригодным для использования и программа вылетает. Когда я пытаюсь напечатать долготу, чтобы увидеть, обновляется ли она, начальное значение выводится несколько раз на терминал, но затем происходит сбой программы, и на карте отсутствует MapCircle

Соответствующая часть Мой файл Qml выглядит следующим образом:

 Map{
        id: map
        anchors.fill:parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(0.5, 0.5)
        zoomLevel:50

        MapCircle{
            id:uavPos
            radius:2
            color:'black'
            border.width:3   
        }

    Connections{
        id:uavConnection
        target: planner
        onUavPositionSet:{

        var data = planner.getUavPosition
        uavPos.center = QtPositioning.coordinate(data[0].latitude, data[0].longitude)
        console.log(data[0].longitude)
        }

        }

    }

Может ли кто-нибудь, пожалуйста, указать мне правильное направление здесь?

1 Ответ

1 голос
/ 16 апреля 2020

Если вы собираетесь обрабатывать информацию из нескольких элементов, то лучше использовать модель (вместе с повторителем для создания нескольких элементов), поэтому необходимо только изменить роль элемента:

gcs.h

#ifndef GCS_H
#define GCS_H

#include <QObject>

class QStandardItemModel;
class QAbstractItemModel;

class GCS: public QObject
{
    Q_OBJECT
    Q_PROPERTY(QObject* uavModel READ uavModel CONSTANT)
public:
    enum UAVRoles {
        PositionRole = Qt::UserRole + 1000
    };
    GCS(QObject *parent=nullptr);
    QObject *uavModel() const;
public Q_SLOTS:
    void triggerPosition();
private:
    QStandardItemModel* m_uavModel;
};

#endif // GCS_H

gcs. cpp

#include "gcs.h"

#include <QGeoCoordinate>
#include <QStandardItemModel>

#include <random>

GCS::GCS(QObject *parent):
    QObject(parent), m_uavModel(new QStandardItemModel(this))
{
    m_uavModel->setItemRoleNames({{PositionRole, "position"}});
    for(int i =0; i < 4; i++){
        QStandardItem *item = new QStandardItem;
        item->setData(QVariant::fromValue(QGeoCoordinate()), PositionRole);
        m_uavModel->appendRow(item);
    }
}

QObject *GCS::uavModel() const{
    return m_uavModel;
}

void GCS::triggerPosition(){
    std::mt19937 rng;
    rng.seed(std::random_device()());
    std::normal_distribution<> dist(-0.0001, +0.0001);

    if(QStandardItem *item = m_uavModel->item(0)){
        QGeoCoordinate uav_id;
        uav_id.setLatitude(0.5 + dist(rng));
        uav_id.setLongitude(0.5 + dist(rng));
        uav_id.setAltitude(5);
        item->setData(QVariant::fromValue(uav_id), PositionRole);
    }
}

main. cpp

#include "gcs.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    GCS gcs;

    QQmlApplicationEngine engine;
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("planner", &gcs);
    const QUrl url(QStringLiteral("qrc:/planner.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    QTimer timer;
    timer.setInterval(1000);
    QObject::connect(&timer, &QTimer::timeout, &gcs, &GCS::triggerPosition);
    timer.start();

    return app.exec();
}

planner.qml

import QtQuick 2.14
import QtQuick.Window 2.14
import QtLocation 5.14
import QtPositioning 5.14

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Plugin {
        id: mapPlugin
        name: "osm"
    }

    Map{
        id: map
        anchors.fill:parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(0.5, 0.5)
        zoomLevel:50

        MapItemView{
            model: planner.uavModel
            delegate: MapCircle{
                id:uavPos
                radius: 2
                color:'black'
                border.width:3
                center: QtPositioning.coordinate(model.position.latitude, model.position.longitude)
            }
        }
    }
}
...