Qt6中QtWebEngineQuick无法加载资源文件内HTML内容的问题
Qt 6.x WebEngineQuick无法加载qrc资源中的HTML文件(Qt 5.15.2正常)
环境与问题描述
Ubuntu 20.04系统(NVIDIA 470显卡),在Qt 6.2.3或Qt 6.4.0版本中运行基于WebEngineQuick的示例时,WebEngineView无法加载qrc资源路径下的HTML文件,但加载网络URL(如https://stackoverflow.com)正常。相同代码在Qt 5.15.2版本中可正常运行。
错误日志如下:
QML debugging is enabled. Only use this in a safe environment. qt.webenginecontext: GLImplementation: desktop Surface Type: OpenGL Surface Profile: CompatibilityProfile Surface Version: 4.6 Using Default SG Backend: yes Using Software Dynamic GL: no Using Angle: no Init Parameters: * application-name recipebrowser * browser-subprocess-path /home/parisa/Applications/Qt/6.2.3/gcc_64/libexec/QtWebEngineProcess * create-default-gl-context * disable-features DnsOverHttpsUpgrade,ConsolidatedMovementXY,InstalledApp,BackgroundFetch,WebOTP,WebPayments,WebUSB,PictureInPicture * disable-setuid-sandbox * disable-speech-api * enable-features NetworkServiceInProcess,TracingServiceInProcess * enable-threaded-compositing * gpu-preferences UAAAAAAAAAAoAAAQAAAAAAAAAAAAAAAAAABgAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAA= * in-process-gpu * use-gl desktop
测试代码
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QtWebEngineQuick/qtwebenginequickglobal.h> int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QtWebEngineQuick::initialize(); 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); return app.exec(); }
main.qml
import QtQuick import QtQuick.Window import QtWebEngine Window { width: 640 height: 480 visible: true title: qsTr("Hello World") WebEngineView { id: webView anchors.fill: parent url: "qrc:/index.html" } }
index.html
<html> <head> </head> <body> <h1>Hello World<h1> </body> </html>
问题成因
Qt 6的WebEngine基于更新版本的Chromium,进程隔离机制与Qt 5不同。WebEngine的子进程(QtWebEngineProcess)默认无法直接访问主进程的qrc资源,导致qrc路径的HTML文件加载失败;而网络URL不受此进程隔离限制,Qt 5.15.2的WebEngine则未引入该严格的隔离规则。
解决方案
1. 使用标准qrc URL格式(优先尝试)
将QML中WebEngineView的url改为三个斜杠的qrc规范格式:
url: "qrc:///index.html"
Qt 6中QUrl对qrc资源的标准写法为qrc:///,部分场景下qrc:/会被Chromium的URL解析器识别为无效路径。
2. 直接加载HTML内容(绕过qrc进程访问限制)
通过QML的XMLHttpRequest读取qrc中的HTML内容,再调用WebEngineView::loadHtml直接加载内容,避免子进程访问qrc资源:
WebEngineView { id: webView anchors.fill: parent Component.onCompleted: { let xhr = new XMLHttpRequest(); xhr.open("GET", "qrc:/index.html"); xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.DONE) { webView.loadHtml(xhr.responseText); } } xhr.send(); } }
3. 禁用WebEngine沙箱(仅调试环境使用)
在main函数中,QtWebEngineQuick::initialize()之前添加环境变量,禁用Chromium沙箱(不推荐生产环境,存在安全风险):
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--no-sandbox");
禁用沙箱后,WebEngine子进程可直接访问qrc资源,但会降低应用安全性。
内容的提问来源于stack exchange,提问作者Parisa.H.R
相关产品推荐
相关产品推荐

