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

QQuickWidget场景下QML调用C++模型方法出错及Plugin问题求助

问题解决:QML调用C++模型方法时报"Cannot call method 'addMarker' of null"

核心问题分析

TypeError: Cannot call method 'addMarker' of null错误的本质是C++端MarkerModel对象生命周期过短:你在MainWindow构造函数中创建的是局部变量MarkerModel model,构造函数执行完毕后该对象会被立即销毁,导致QML中的markerModel引用变成空指针,无法调用其方法。

另外之前出现的"QML Map: Plugin is a write-once property, and cannot be set again"错误,通常是Map的plugin属性被重复赋值导致,先解决核心的对象生命周期问题后可同步验证。

解决方案

1. 修改MainWindow头文件,添加成员变量

在mainwindow.h中声明MarkerModel成员,确保其生命周期与MainWindow一致:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "locationMarker.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    MarkerModel m_markerModel; // 声明成员变量
};
#endif // MAINWINDOW_H

2. 调整mainwindow.cpp中的代码

将原局部变量替换为成员变量:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "locationMarker.h"

#include <QQmlContext>
#include <QQuickWidget>
#include <QQmlEngine>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 使用成员变量传递给QML上下文
    ui->quickWidget->engine()->rootContext()->setContextProperty("markerModel", &m_markerModel);
    ui->quickWidget->setSource(QUrl("qrc:/map.qml"));
}

MainWindow::~MainWindow()
{
    delete ui;
}

3. 验证Plugin设置(可选)

若仍出现Plugin重复赋值错误,确认QML中Map的plugin仅赋值一次:当前map.qml中Plugin作为Item子对象、Map直接引用osmPlugin的写法是正确的,只需确保无其他代码重复给mapview.plugin赋值即可。

其他注意事项

  • 确保MarkerModel的addMarker方法已用Q_INVOKABLE修饰(你已完成此设置),保证QML能调用该方法。
  • 保持setSource在设置上下文属性之后执行,当前代码顺序符合要求。

内容的提问来源于stack exchange,提问作者A A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:05:24