gpt4 book ai didi

c++ - 当 main.qml 通过 HTTP 导入时,main.cpp 中的 "engine.rootObjects().first()"崩溃

转载 作者:行者123 更新时间:2023-12-03 06:53:23 24 4
gpt4 key购买 nike

我们有一行代码,我一直(或更长时间)使用它来获取指向根窗口的指针。我们最近开始使用 HTTP 语法从服务器导入我们的组件。当我们将 then 放在一起时,程序崩溃,engine.rootObjects().first() 返回空。这是一个简化的“main.cpp”:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;

const QUrl url(QStringLiteral("qrc:/main.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);

QObject* rootWindowPointer = (engine.rootObjects().first()); // <-- this is the function that fails

return app.exec();
}

这里是一个简化的“main.qml”,其中包含导致问题的导入:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

import "http://eggs:88/empty" // <-- this is the added line that caused the problem

ApplicationWindow {
id: window
visible: true
width: 200
height: 100
title: qsTr("Liblo Server Test")

Text {
text: "Made it this far . . ."
anchors.centerIn: parent
}
}

如果我们在 main.cpp 中注释掉以下获取根窗口指针的行,程序将运行:

QObject* rootWindowPointer = (engine.rootObjects().first();

如果我们在 main.qml 中注释掉以下“导入”我们的组件的行,程序也会运行:

导入“http://eggs:88/empty”

但是,如果您同时启用了这两条线,那么当 main.cpp 中的那条线试图获取指针时,您会遇到以下崩溃:

20:37:03: Starting /xxxx/mark/QtApps/build-libloServer-Desktop_Qt_5_15_0_GCC_64bit-Debug/rootwindow ...
QML debugging is enabled. Only use this in a safe environment.
ASSERT: "!isEmpty()" in file ../../Qt/5.15.0/gcc_64/include/QtCore/qlist.h, line 361
20:37:04: The program has unexpectedly finished.
20:37:04: The process was ended forcefully.
20:37:04: /xxxx/xxxx/QtApps/build-libloServer-Desktop_Qt_5_15_0_GCC_64bit-Debug/rootwindow crashed.

不知道为什么这两件事会相关,我们认为这可能是时机(不太可能,但可能)。所以我们在指针获取前放了一个等待线:

做 {} while ( engine.rootObjects().isEmpty());

但它永远不会变为非空。我们还尝试了我们真正的 HTTP 库、一个空库和一个伪造的 URL,每次都得到完全相同的结果(因此您可以在没有实际 URL 的情况下进行尝试)。

有人知道为什么会这样吗?

如果这是一个不起眼的错误,有人能想出解决方法吗?

是否有另一种方法获取指向根窗口的指针以供 C++ 使用?

最佳答案

没有什么晦涩难懂,但这是预期的行为。当对象完成构建时,rootObjects 被分配给 C++,因为你有一个异步加载 url (http),所以构建是异步的。所以如果你想获得 root,那么你必须使用 objectCreated 信号:

QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url, &engine](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
else{
if(engine.rootObjects().isEmpty())
return;
QObject* rootWindowPointer = engine.rootObjects().first();
qDebug() << rootWindowPointer;
}
}, Qt::QueuedConnection);

关于c++ - 当 main.qml 通过 HTTP 导入时,main.cpp 中的 "engine.rootObjects().first()"崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64815748/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com