How work with QWebEngineUrlRequestJob?
-
I have inherited from QWebEngineUrlSchemeHandler. Redefined method requestStarted(QWebEngineUrlRequestJob *request)
After I try to call QWebEngineUrlRequestJob::reply
for examplevoid CustomUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
qDebug() << "CustomUrlSchemeHandler::requestStarted -->>> " << request->requestUrl();QMimeDatabase HelpViewer; QMimeType mt = HelpViewer.mimeTypeForUrl(request->requestUrl()); const QString mimeType = mt.name(); QByteArray arr = QString::fromStdString("<html><body>Hello world</body></html>").toUtf8(); QBuffer *buffer = new QBuffer(&arr, this); buffer->open(QIODevice::ReadOnly); request->reply(mimeType.toLatin1(), buffer); return;}
But the program crashes.
pls see more detail - http://stackoverflow.com/questions/33933958/qt-5-6-beta-qtwebengine-how-work-with-qwebengineurlrequestjob -
The reason of the crash is not obvious, because Qt documentation is not clear on the details how
QWebEngineUrlSchemeHandlershould be implemented.Your program crashes because
QWebEngineUrlRequestJob::reply()uses the buffer parameter later, out of the caller's scope, probably from a different thread. The local variableQByteArrayarr which you declared on the stack (and used as backing storage for the buffer) will be out of scope by then and QWebEngine will be accessing an invalid pointer.Another thing is,
reply()does not take ownership of the passed buffer object and never deletes it. This introduces a memory leak. You cannot simply delete it right after callingreply()for the same reason as above. To ensure the buffer object is deleted when no longer needed, connect the request'sdestroyed()signal to the buffer'sdeleteLater()slot.Here is a complete working and leak-free example:
void CustomUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request) { QBuffer *buffer = new QBuffer; connect(request, SIGNAL(destroyed()), buffer, SLOT(deleteLater())); buffer->open(QIODevice::WriteOnly); buffer->write("<html><body>Hello world!</body></html>"); buffer->close(); request->reply("text/html", buffer); }Note: You don't need to use a
QByteArrayat all. The default constructor forQBufferallocates its own storage. -
I have inherited from QWebEngineUrlSchemeHandler. Redefined method requestStarted(QWebEngineUrlRequestJob *request)
After I try to call QWebEngineUrlRequestJob::reply
for examplevoid CustomUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
qDebug() << "CustomUrlSchemeHandler::requestStarted -->>> " << request->requestUrl();QMimeDatabase HelpViewer; QMimeType mt = HelpViewer.mimeTypeForUrl(request->requestUrl()); const QString mimeType = mt.name(); QByteArray arr = QString::fromStdString("<html><body>Hello world</body></html>").toUtf8(); QBuffer *buffer = new QBuffer(&arr, this); buffer->open(QIODevice::ReadOnly); request->reply(mimeType.toLatin1(), buffer); return;}
But the program crashes.
pls see more detail - http://stackoverflow.com/questions/33933958/qt-5-6-beta-qtwebengine-how-work-with-qwebengineurlrequestjob@treem
Can you tell me how to work with QWebEngineUrlSchemeHandler?I have inherited from QWebEngineUrlSchemeHandler and QWebEnginePage,and In Constructor of WebEnginePage, I wrote:
WebEngineUrlSchemeHandler *weush = new WebEngineUrlSchemeHandler; profile->installUrlSchemeHandler(QByteArray("qthelp:"),weush);but it dose not work.