I am currently developing an application for Windows using Qt 5.9 that displays some local HTML files inside using a QWebEngineView
instance. The code is rather simple, and I don't think it is relevant to the issue at hand:
QWebEngineView *webView = new QWebEngineView(this);
webView->setUrl(QUrl("qrc:/my_view.html"));
This works nicely on my development machine, on both debug and release configurations. My application is already on production and as such it can be installed using the Qt Installer Framework. I am using windeployqt for deployment. Again, the installed binary works renders the web pages on my machine with no issues. However, on a different machine with the same OS, it will crash whenever the web view is instantiated.
After some debugging, here are my discoveries:
According to the documentation on the web engine:
Qt WebEngine requires the following resource files:
qtwebengine_resources.pak contains the resources needed by Chromium. qtwebengine_devtools_resources.pak contains tools for remote debugging. qtwebengine_resources_100p.pak contains images suitable for low resolution displays. qtwebengine_resources_200p.pak contains images suitable for high DPI displays. icudtl.dat provides support for International Components for Unicode (ICU). It is the Chromium version of ICU, which is not needed if Qt WebEngine was configured to use the system ICU.
Resources are searched from the following locations:
On Linux and Windows: the resources directory in the directory specified by QLibraryInfo::location(QLibraryInfo::DataPath)
Which I found odd, since the output of the application directory yields the following (trimmed for convenience):
│ app.exe
| <other libraries>
│ Qt5WebChannel.dll
│ Qt5WebEngineCore.dll
│ Qt5WebEngineWidgets.dll
│ QtWebEngineProcess.exe
│
├───bearer
│
├───iconengines
│
├───imageformats
│
├───Licenses
│
├───platforms
│
├───position
│
├───printsupport
│
├───resources
│ icudtl.dat
│ qtwebengine_devtools_resources.pak
│ qtwebengine_resources.pak
│ qtwebengine_resources_100p.pak
│ qtwebengine_resources_200p.pak
│
├───sqldrivers
│
└───translations
└───qtwebengine_locales
Which clearly shows that the web engine files are in theory properly located. I tried debugging the value of QLibraryInfo::location(QLibraryInfo::DataPath)
, and it yielded C:/Qt/Qt5.9.2/5.9.2/msvc2017_64
, which isn't even a directory on the target machine, but rather on my development PC. Instead, I think it should output the path to ./resources
.
If I place the files mentioned in the docs in the same directory as the application binary it runs as it should, but I would have expected the QLibraryInfo::DataPath
to automatically detect where this directory is instead of, by the looks of it, being a hard-coded value.
As such I would like to ask the following:
- Am I doing this deployment correctly? I have never had any problems with the application being unable to load the Qt libraries of any sort, and the files seem to be where they should be.
- How does
QLibraryInfo::location(QLibraryInfo::DataPath)
exactly resolve paths? Are they hard coded values or are they determined during runtime? - What would be the most sensible way to make the application find the resources? I am thinking of the following solutions:
Manually place the files under
./resources
close to the application binary.Adding the
./resources
to the search path withQCoreApplication::addLibraryPath()
(I am not sure if it will work).Play around with a
qt.conf
file. Again unsure if it will work. Edited: This does indeed work. Oddly enough it did not if the file was compiled as a Qt resource (as in:/qt/etc/qt.conf
), but if you place the text file along the application binary it will automatically use it. My file looks simply like this:[Paths]
Data = ./resources