Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QWebEngineView crashes on load() or page() method

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++
like image 925
Vern Jensen Avatar asked Feb 12 '16 03:02

Vern Jensen


2 Answers

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.

like image 89
Vern Jensen Avatar answered Oct 18 '22 11:10

Vern Jensen


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

like image 28
Davide Berra Avatar answered Oct 18 '22 10:10

Davide Berra