无法从QML向C++传递数据,Qt 5.15.2报错求助
运行错误信息
QObject::connect(QQuickWindow, QDeclarativeGeoMap): invalid nullptr parameter
QObject::connect(QQuickWindow, QDeclarativeGeoMap): invalid nullptr parameter
QGeoTileProviderOsm: Tileserver disabled at QUrl("http://maps-redirect.qt.io/osm/5.8/satellite")
QGeoTileFetcherOsm: all providers resolved
QGeoTileProviderOsm: Tileserver disabled at QUrl("http://maps-redirect.qt.io/osm/5.8/satellite")
QGeoTileFetcherOsm: all providers resolved
环境信息
使用Qt版本:5.15.2
相关代码
QML部分代码
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtLocation 5.15 import QtPositioning 5.15 import QtQuick.Dialogs 1.3 Rectangle { id: telecom width: 800 height: 600 signal setRect(double x, double y, double width, double height) Plugin { id: mapPlugin name: "osm" } Map { id: map anchors.fill: parent plugin: mapPlugin center: QtPositioning.coordinate(55.7558, 37.6173) zoomLevel: 10 MouseArea { id: mapMouseArea anchors.fill: parent onPressed: { mapMouseArea.active = true } onReleased: { mapMouseArea.active = false } } } Rectangle { id: rect width: 0 height: 0 color: "blue" opacity: 0.5 border.color: "black" border.width: 2 visible: false x: 100 y: 100 } MouseArea { id: mouseArea anchors.fill: parent onPressed: { rect.x = mouseArea.mouseX rect.y = mouseArea.mouseY rect.width = 0 rect.height = 0 rect.visible = true } onReleased: { rect.width = Math.abs(mouseArea.mouseX - rect.x) rect.height = Math.abs(mouseArea.mouseY - rect.y) setRect(rect.x, rect.y, rect.width, rect.height) } ...
main.cpp代码
int main(int argc, char *argv[]) { QApplication a(argc, argv); QQmlApplicationEngine engine; RectangleHandler rectangleHandler; engine.rootContext()->setContextProperty("rectangleHandler", &rectangleHandler); const QUrl url(QStringLiteral("qrc:/places_map.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &a, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) { qCritical() << "Error 1"; QCoreApplication::exit(-1); } }, Qt::QueuedConnection); engine.load(url); if (engine.rootObjects().isEmpty()) { qCritical() << "Error 2"; return -1; } MainWindow w; w.show(); return a.exec(); }
核心需求
需将QML中绘制的矩形坐标数据传递至C++做后续处理,但运行时触发上述错误,求解决方法。
解决方案
1. 修复invalid nullptr parameter连接错误
代码中同时使用QQmlApplicationEngine加载QML和MainWindow,导致QML的Map控件无法找到对应QQuickWindow,触发空指针连接错误。
- 修复方式:二选一使用QML窗口或Qt Widgets窗口。若要保留QML的
Map控件,需移除MainWindow相关代码,并将QML根元素改为ApplicationWindow:- 修改后的main.cpp:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QQmlApplicationEngine engine; RectangleHandler rectangleHandler; engine.rootContext()->setContextProperty("rectangleHandler", &rectangleHandler); const QUrl url(QStringLiteral("qrc:/places_map.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &a, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) { qCritical() << "Error 1"; QCoreApplication::exit(-1); } }, Qt::QueuedConnection); engine.load(url); if (engine.rootObjects().isEmpty()) { qCritical() << "Error 2"; return -1; } return a.exec(); } - 修改QML根元素:
import QtQuick.Window 2.15 ApplicationWindow { id: telecom width: 800 height: 600 visible: true // 原Rectangle内的所有内容移至此处 signal setRect(double x, double y, double width, double height) Plugin { id: mapPlugin name: "osm" } // ... 其余代码保持不变 }
- 修改后的main.cpp:
2. 实现QML信号到C++的传递
当前QML定义了setRect信号,但未连接到C++的rectangleHandler对象,需补充连接逻辑:
- 在QML中添加信号连接:
Component.onCompleted: { telecom.setRect.connect(rectangleHandler.onSetRect) } - 确保
RectangleHandler类继承QObject并定义对应槽函数:#include <QObject> class RectangleHandler : public QObject { Q_OBJECT public slots: void onSetRect(double x, double y, double width, double height) { // 在此处理传递过来的矩形数据 } };
3. 修复地图瓦片服务禁用问题
Qt 5.15.2默认的OSM卫星瓦片地址已失效,需手动指定可用的瓦片源:
Plugin { id: mapPlugin name: "osm" PluginParameter { name: "osm.mapping.providersrepository.disabled" value: true } PluginParameter { name: "osm.mapping.providers.order" value: "custom" } PluginParameter { name: "osm.mapping.provider.custom.type" value: "xyz" } PluginParameter { name: "osm.mapping.provider.custom.url" value: "https://tile.openstreetmap.org/{z}/{x}/{y}.png" } PluginParameter { name: "osm.mapping.provider.custom.zenith" value: 0 } PluginParameter { name: "osm.mapping.provider.custom.azimuth" value: 0 } }
内容的提问来源于stack exchange,提问作者3614n

