You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从QML向C++传递数据,Qt 5.15.2报错求助

问题:QML向C++传递数据时出现连接错误及地图瓦片服务异常

运行错误信息

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"
          }
      
          // ... 其余代码保持不变
      }
      

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:05:04