我正在使用 QtWebKit,在其中显示动态创建的 HTML 内容,并且我需要显示从数据库检索的图像。例如,如果我需要显示资源中的图像,我会将此行添加到我在 QWebView::setHtml 中使用的内容中:
<img src="qrc:/images/image.jpg"/>
效果很好,WebView 会自动查找资源并显示它。现在我需要用从数据库检索的内容替换该图像,并且文件系统中没有文件。如何做到这一点?
我可以管理动态添加内容的qrc命名空间吗?是否可以添加我自己的 QRC 处理程序来接收和服务来自 WebView 的请求?如果不是 QRC,是否有任何其他协议(protocol)可以用来向 WebView 中的图像提供内容?
我可以使用 setHtml
方法完全控制要添加到 WebView 的内容。
更新:我也想为QWebEngineView解决同样的问题。
最佳答案
QtWebkit
对于 QtWebkit,您必须使用 QNetworkAccessManager 拦截请求并重新发送自定义 QNetworkReply。
#include <QtWebKitWidgets>
class CustomReply : public QNetworkReply{
public:
explicit CustomReply(const QByteArray & content, const QByteArray & contentType, const QUrl & url):
QNetworkReply(), m_content(content){
offset = 0;
setUrl(url);
open(ReadOnly | Unbuffered);
setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType));
setHeader(QNetworkRequest::ContentLengthHeader, QVariant(m_content.size()));
QTimer::singleShot(0, this, &CustomReply::dispatch);
}
bool isSequential() const{
return true;
}
qint64 bytesAvailable() const{
return m_content.size() - offset + QIODevice::bytesAvailable();
}
public slots:
void abort(){
}
protected:
qint64 readData(char *data, qint64 maxSize){
if (offset < m_content.size()) {
qint64 number = qMin(maxSize, m_content.size() - offset);
::memcpy(data, m_content.constData() + offset, number);
offset += number;
return number;
} else
return -1;
}
private:
void dispatch(){
emit readyRead();
emit finished();
}
QByteArray m_content;
qint64 offset;
};
class NetworkAccessManager: public QNetworkAccessManager{
public:
using QNetworkAccessManager::QNetworkAccessManager;
protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData){
qDebug() << request.url();
if (request.url() == QUrl("qrc:/images/image.jpg")){
QImage image(150, 150, QImage::Format_RGB32);
image.fill(QColor("salmon"));
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "JPEG");
return new CustomReply(ba, "image/jpeg", request.url());
}
return QNetworkAccessManager::createRequest(op, request, outgoingData);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWebView view;
view.resize(640, 480);
view.show();
view.page()->setNetworkAccessManager(new NetworkAccessManager);
QString html = R"(<img src="qrc:/images/image.jpg">)";
view.setHtml(html);
return a.exec();
}
QtWebEngine
在 QtWebEngine 中,您必须实现 QWebEngineUrlSchemeHandler,但不能使用 qrc、http 或 https 架构:
#include <QtWebEngineWidgets>
#define SCHEMENAME "so"
class Handler : public QWebEngineUrlSchemeHandler{
public:
void requestStarted(QWebEngineUrlRequestJob *job){
if(job->requestUrl() == QUrl("so:/images/image.jpg")){
QImage image(150, 150, QImage::Format_RGB32);
image.fill(QColor("salmon"));
QBuffer *buffer = new QBuffer;
buffer->open(QIODevice::WriteOnly);
image.save(buffer, "JPEG");
buffer->seek(0);
buffer->close();
job->reply("image/jpeg", buffer);
}
}
static void registerUrlScheme(){
QWebEngineUrlScheme webUiScheme(SCHEMENAME);
webUiScheme.setFlags(QWebEngineUrlScheme::SecureScheme |
QWebEngineUrlScheme::LocalScheme |
QWebEngineUrlScheme::LocalAccessAllowed);
QWebEngineUrlScheme::registerScheme(webUiScheme);
}
};
int main(int argc, char *argv[])
{
Handler::registerUrlScheme();
QApplication a(argc, argv);
QWebEngineView view;
Handler handler;
view.page()->profile()->installUrlSchemeHandler(SCHEMENAME, &handler);
view.resize(640, 480);
view.show();
QString html = R"(<img src="so:/images/image.jpg">)";
view.setHtml(html);
return a.exec();
}
关于qt - 如何在QWebView中显示动态创建的图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63095511/