使用 QQuickImageProvider 在 QML WebEngineView 中加载图像
Posted
技术标签:
【中文标题】使用 QQuickImageProvider 在 QML WebEngineView 中加载图像【英文标题】:Load image in QML WebEngineView using QQuickImageProvider 【发布时间】:2018-04-10 04:53:40 【问题描述】:我正在使用 loadhtml
方法将 HTML 内容注入 QML WebEngineView,并试图让它通过 QQuickImageProvider 加载图像。
到目前为止,我们已经成功地从 Qt 资源容器 (qrc) 加载图像,但这还不够灵活。
contentimageprovider.cpp
#include "contentimageprovider.h"
#include <QDebug>
ContentImageProvider::ContentImageProvider() : QQuickImageProvider(QQuickAsyncImageProvider::Image)
QImage ContentImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
qDebug() << __FUNCTION__ << id;
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtWebEngine/QtWebEngine>
#include "contentimageprovider.h"
int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QtWebEngine::initialize();
engine.addImageProvider(QLatin1String("content-images"), new ContentImageProvider);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import QtWebEngine 1.4
Image
source: "image://content-images/this-image-is-requested";
WebEngineView
Component.onCompleted:
loadHtml("<img src='qrc://images/this-image-is-displayed.png' /><img src='image://content-images/this-image-should-also-be-requested' />", "/");
预期输出
requestImage "this-image-is-requested"
requestImage "this-image-should-also-be-requested"
实际输出
requestImage "this-image-is-requested"
并显示WebEngineView中通过qrc加载的图片,另一张则显示破损图片。
有没有人能够让它工作?
【问题讨论】:
"这不够灵活" 您正在混合使用 QML 和 HTML。 ImageProviders 可以在 QML 中使用,但它们对于 HTML-Engine 或其他什么是未知的。 HTML 中的 image:// 链接将被理解为 WebEngine 中的 URL-Handler(如 mailto:、sendto:、tell:、skype: 等)。因此,如果您需要 image: 处理程序,您需要在 WebEngine 中声明和定义它。看看 QWebEngineUrlSchemeHandler -> doc.qt.io/qt-5/qwebengineurlrequestinterceptor.html 【参考方案1】:感谢@Xplatforms 指出最初假设QML WebEngineView 下的Chromium 引擎会与QML Quick 引擎交互并触发图像提供程序的错误。
解决方案是实现一个QWebEngineUrlSchemeHandler:
void ImageRequestHandler::requestStarted(QWebEngineUrlRequestJob *request)
// request->requestUrl() is a QUrl
QFile *image = new QFile(QDir::currentPath() + "/storage/content/" + request->requestUrl().path() + ".png");
// makes sure the image deletes itself when closing the file
connect(image, &QIODevice::aboutToClose, image, &QObject::deleteLater);
// close the file when the request job is done
connect(request, &QObject::destroyed, image, &QIODevice::close);
QMimeDatabase mimeDB;
QMimeType mimeType = mimeDB.mimeTypeForFile(image->fileName());
request->reply(mimeType.name().toUtf8(), image);
main.cpp
int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// web engine to provide content display
QtWebEngine::initialize();
// intercept requests from the web engine to provide locally loaded content and images
ImageRequestHandler *imageRequestHandler = new ImageRequestHandler();
QQuickWebEngineProfile::defaultProfile()->installUrlSchemeHandler("image", imageRequestHandler);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
【讨论】:
以上是关于使用 QQuickImageProvider 在 QML WebEngineView 中加载图像的主要内容,如果未能解决你的问题,请参考以下文章
通过按钮单击触发带有参数的 QQuickImageProvider::requestImage()