QObject::connect空指针错误及Release版QQuickWidget不显示问题求助
invalid nullptr parameter报错 针对Qt Creator运行正常、Release版exe无法显示QQuickWidget且报错QObject::connect(QQuickWindow, QDeclarativeGeoMap): invalid nullptr parameter的问题,可按以下步骤排查解决:
1. 修正QML资源加载路径
代码中使用QUrl::fromLocalFile(":/Map_QML.qml")容易混淆本地文件与资源文件路径,建议改为标准资源路径写法:
ui->MapWidget->setSource(QUrl("qrc:/Map_QML.qml"));
同时确保.pro文件已正确配置资源项:
RESOURCES += your_resource_file.qrc
2. 手动补充QtLocation地理服务插件
windeployqt常无法完整部署QtLocation的osm插件,需从Qt安装目录(如Qt5.15.2/5.15.2/msvc2019_64/plugins/geoservices)复制整个geoservices文件夹到exe同级目录,确保包含qtgeoservices_osm.dll和osm.ini等文件。
3. 部署QtPositioning插件
从Qt安装目录的plugins/positioning文件夹复制到exe同级,确保qtpositioning_nmea.dll等插件文件存在。
4. 确认SSL库完整性
根据Qt版本复制对应SSL库到exe目录:
- Qt5早期:
libeay32.dll、ssleay32.dll - Qt5后期/Qt6:
libcrypto-1_1-x64.dll、libssl-1_1-x64.dll
这些文件位于Qt安装目录的bin文件夹下。
5. 确保QML模块完整部署
重新运行windeployqt时明确指定QML文件所在目录,例如:
windeployqt --qmldir ./path/to/your/qml/files your_app.exe
这会自动复制QtQuick、QtLocation、QtPositioning所需的QML模块到exe同级的qml目录。
6. 添加QML错误调试输出
在MapWindow构造函数中添加QML引擎警告输出,便于定位加载错误:
#include <QQmlEngine> #include <QQmlError> #include <QDebug> // 在MapWindow构造函数的ui->setupUi(this);之后添加 connect(ui->MapWidget->engine(), &QQmlEngine::warnings, [](const QList<QQmlError>& warnings) { for (const auto& warning : warnings) { qDebug() << "[QML Warning]" << warning.toString(); } });
编译Release版后,通过控制台运行exe查看输出的错误信息。
7. 固定程序工作目录
在main.cpp开头添加代码,确保程序工作目录为exe所在路径:
#include <QDir> #include <QCoreApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDir::setCurrent(QCoreApplication::applicationDirPath()); // 添加这行 // ... 其他代码 return a.exec(); }
附:调整后的代码参考
mainwidget.cpp
#include "mainwidget.h" #include "ui_mainwidget.h" #include "mapwindow.h" MainWidget::MainWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::MainWidget) { ui->setupUi(this); map_window = new MapWindow(); connect(map_window, &MapWindow::return_on_main_window, this, &MainWidget::show); } MainWidget::~MainWidget() { delete ui; } void MainWidget::on_MapButton_clicked() { map_window->show(); this->close(); }
mapwindow.cpp
#include "mapwindow.h" #include "ui_mapwindow.h" #include <QQmlEngine> #include <QQmlError> #include <QDebug> MapWindow::MapWindow(QWidget *parent) : QDialog(parent), ui(new Ui::MapWindow) { ui->setupUi(this); // 添加QML错误调试 connect(ui->MapWidget->engine(), &QQmlEngine::warnings, [](const QList<QQmlError>& warnings) { for (const auto& warning : warnings) { qDebug() << "[QML Warning]" << warning.toString(); } }); ui->MapWidget->setSource(QUrl("qrc:/Map_QML.qml")); ui->MapWidget->show(); } MapWindow::~MapWindow() { delete ui; } void MapWindow::on_ReturnButton_clicked() { this->close(); emit return_on_main_window(); }
Map_QML.qml
import QtQuick 2.0 import QtPositioning 5.15 import QtLocation 5.15 Rectangle { id: window property double oldLat: 49.45466 property double oldLng: 30.52380 property Component comMarker: mapMarker Plugin { id: mapPlugin name: "osm" PluginParameter { name: "osm.mapping.providersrepository.disabled" value: "true" } PluginParameter { name: "osm.mapping.providersrepository.address" value: "http://maps-redirect.qt.io/osm/5.6/" } } Map { id: mapView anchors.fill: parent plugin: mapPlugin center: QtPositioning.coordinate(oldLat, oldLng); zoomLevel: 5.5 } function setCenter(lat, lng) { mapView.pan(oldLat - lat, oldLng - lng) oldLat = lat oldLng = lng } function addMarker(lat, lng) { var item = comMarker.createObject(window, { coordinate: QtPositioning.coordinate(lat, lng) }) mapView.addMapItem(item) } Component { id: mapMarker MapQuickItem { id: markerImg anchorPoint.x: image.width/4 anchorPoint.y: image.height coordinate: position sourceItem: Image { id: image source: "http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png" } } } }
内容的提问来源于stack exchange,提问作者EviiiiL

