I'm working on porting a Qt 5.5, QWebView project to Qt 5.6 (beta), QWebEngine. I've gone through the porting guide here. My code looks like this:
.h file defines _view like so:
QWebEngineView* _view;
and the .cpp constructor (class inherits from QWidget) has:
QVBoxLayout* vbox = new QVBoxLayout(this);
_view = new QWebEngineView(this);
connect(_view, SIGNAL(loadFinished(bool)), this, SLOT(loadPageFinished(bool)));
QString webDir = getReportBasePath() + no_tr("/index.html#") + startingPage;
// QWebEnginePage *page = _view->page(); // <-- CRASH!!
_view->load( QUrl("file:///" + webDir ) ); // <-- CRASH!!
_view->show();
vbox->addWidget(_view);
Upon doing either the page() or load() method, the whole thing crashes with:
Unhandled exception at 0x67019C66 (Qt5Cored.dll) in qxs.exe: 0xC0000005:
Access violation reading location 0x00000000.
I've verified that the _view pointer is not null.
If you look at the documentation, they have an example here that's almost identical to my code above. I've also tried replacing load() call to be identical to theirs:
view->load(QUrl("http://qt-project.org/"));
and it still crashes. Any ideas what could be causing these crashes?
Do I need to create a QWebEnginePage first and setPage() on the QWebEngineView? (I'm assuming not...) Could it have something to do with the Qt binaries (pre-built for Windows 32-bit MSVC 2013) that I'm using?
Relevant part of stack trace:
Qt5WebEngineWidgetsd.dll!QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile * _profile) Line 95 C++
Qt5WebEngineWidgetsd.dll!QWebEnginePage::QWebEnginePage(QObject * parent) Line 393 C++
Qt5WebEngineWidgetsd.dll!QWebEngineView::page() Line 145 C++
Qt5WebEngineWidgetsd.dll!QWebEngineView::load(const QUrl & url) Line 157 C++
qxs.exe!ReportWidget::ReportWidget(QcaMain * qm, QWidget * parent, QString startingPage) Line 321 C++
It crashes here:
QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
: adapter(new WebContentsAdapter)
, history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this)))
, profile(_profile ? _profile : QWebEngineProfile::defaultProfile())
, settings(new QWebEngineSettings(profile->settings()))
, view(0)
, isLoading(false)
, scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
, m_backgroundColor(Qt::white)
, fullscreenMode(false)
{
memset(actions, 0, sizeof(actions));
}
I thought maybe that had something to do with _profile being NULL, so I attempted to first set a QWebEngineProfile like so:
QWebEnginePage* page = new QWebEnginePage( QWebEngineProfile::defaultProfile(), _view );
_view->setPage( page );
Then it instead crashes in qwebengineprofile.cpp here:
static QWebEngineProfile* profile = new QWebEngineProfile(
new QWebEngineProfilePrivate(BrowserContextAdapter::defaultContext()),
BrowserContextAdapter::globalQObjectRoot());
with stack trace:
Qt5Cored.dll!convert_to_wchar_t_elided(wchar_t * d, unsigned int space, const char * s) Line 256 C++
Qt5Cored.dll!qt_message_fatal(QtMsgType __formal, const QMessageLogContext & context, const QString & message) Line 1593 C++
Qt5Cored.dll!QMessageLogger::fatal(const char * msg, ...) Line 784 C++
Qt5WebEngineCored.dll!`anonymous namespace'::subProcessPath(void) C++
Qt5WebEngineCored.dll!WebEngineLibraryInfo::getPath(int) C++
Qt5WebEngineCored.dll!WebEngineContext::WebEngineContext(void) C++
Qt5WebEngineCored.dll!WebEngineContext::current(void) C++
Qt5WebEngineCored.dll!QtWebEngineCore::BrowserContextAdapter::defaultContext(void) C++
> Qt5WebEngineWidgetsd.dll!QWebEngineProfile::defaultProfile() Line 516 C++
Problem solved. I was missing some key files required by QWebEngine, otherwise it'll crash. These files must be in the same directory as the executable. They are put there by the windeployqt.exe tool, so that's the best way to ensure your Qt application has everything it needs to run without crashing.
qtwebengine_resources.pak
qtwebengine_resources_100p
qtwebengine_resources_200p.pak.pak
QtWebEngineProcess.exe
icudtl.dat
The reason this got me was our development group was formerly using Qt 4.8, and uses an in-house method to copy the required Qt dlls and whatnot into the target directory. When upgrading to Qt 5.x and adding QWebEngine, we didn't realize the files above were required.
You can set Windows environment variable called QTWEBENGINEPROCESS_PATH
Example:
QTWEBENGINEPROCESS_PATH C:\Qt\Qt5.6.0\5.6\msvc2013_64\bin\QtWebEngineProcess.exe
With this solution, no need to copy resources files into your projects output folders
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With