[英]Update a MapCircle on QML using a signal from C++
I'm trying to update a MapCircle in QML from a signal in C++ and I'm veen having several issues with it all day.我正在尝试从 C++ 中的信号更新 QML 中的 MapCircle,我整天都遇到几个问题。
In my class I have a Q_PROPERTY
which is read only and holds the GPS positions of 4 UAVs in a QVariantList
在我的 class 中,我有一个Q_PROPERTY
,它是只读的,并且在QVariantList
中保存 4 个 UAV 的 GPS 位置
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;
};
I then define the functions as:然后我将函数定义为:
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");
}
In my main function, I connect triggerPosition
to a Timer so as to update the position periodically在我的主要 function 中,我将triggerPosition
连接到 Timer 以便定期更新 position
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();
}
However, when I run my program, there's a slight delay, my mouseArea
becomes unusable and the program crashes.但是,当我运行我的程序时,会有一点延迟,我的mouseArea
变得不可用并且程序崩溃了。 When I try to print the longitude to see if it updates, The initial value is printed out multiple times to the terminal but then the program crashes and there's is no MapCircle
present on the map当我尝试打印经度以查看它是否更新时,初始值被多次打印到终端,但随后程序崩溃并且 map 上没有MapCircle
The relevant part of My Qml file looks like this:我的 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)
}
}
}
Can someone please kindly point me in the right direction here?有人可以在这里指出我正确的方向吗?
If you are going to handle information from several elements then it is better to use a model (together with a Repeater to create several elements), so it is only necessary to modify the role of an item:如果您要处理来自多个元素的信息,那么最好使用 model(与中继器一起创建多个元素),因此只需修改一个项目的角色:
gcs.h 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 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规划师.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)
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.