Creating a Qt install package with InnoSetup : missing images - qt

I'm developing a Qt app in Qt Creator. I'm creating an install package via InnoSetup. And everything works OK except all the images are missing in the installed program (running it in Qt Creator works fine).
I'm using The Qt Resource System
In my .pro file I have
RESOURCES += \
res/resources.qrc
If in my resources.qrc I have something like this:
<RCC>
<qresource prefix="/icons">
<file>4000003.png</file>
...
</qresource>
</RCC>
I access my images for example like this:
title->setIcon(QPixmap(":/icons/" + QString::number(id) + ".png"));
The structure of my directory is :
MyApp
-sources files (i.e. `.cpp`, `.h`)
-res/
-all the images
-resources.qrc
build-release
-release/
- MyApp.exe
So should I have exactly the same struture in InnoSetup? Meaning I should have the build-release\release directory and the MyApp\res as well? Because I tried that and it didn't help.

Related

How to rightly add resources in Qt application

I am trying to deploy windows application in Qt, so I change mode to release, but when I execute it, all it writes is
file::/qml/Main.qml: File is empty
I have already tried multiple times to rework resources.qrc, but with no success.
resources.qrc
<RCC>
<qresource prefix="/">
<file>qml/Pages/DetailPage.qml</file>
<file>qml/Pages/IntroPage.qml</file>
<file>qml/Pages/LibaryPage.qml</file>
<file>qml/Pages/Page.qml</file>
<file>qml/Pages/PageView.qml</file>
<file>qml/Controls/ControlSlider.qml</file>
<file>qml/Models/CityModel.qml</file>
<file>images/heatmapicon.png</file>
<file>qml/Main.qml</file>
</qresource>
</RCC>
I have tried to copy qml and images folder (they are in same folder as main.cpp and resources.qrc), but no success too.
This is how I set main source for QQuickView :
view_->setSource(QUrl::fromLocalFile(QStringLiteral(":/qml/Main.qml")));
In debug mode, there is no problem and everything start as it should.
How can I change resource/code to make it work?
Thanks for your help!
//EDIT:
I have manage to solve it with view_>setSource(QUrl(QStringLiteral("qrc:/qml/Main.qml")));
You do not have to use QUrl::fromLocalFile(), that function is indicating that you are looking for a local file, but the paths handled by a .qrc are virtual.
Use:
view_->setSource(QUrl(QStringLiteral("qrc:/qml/Main.qml")));

Use a precompiled plugin (via a shared library) in a QML application

I have a QML plugin compiled (to a .so) by another project. I want to re-use this in my own QML application without re-building it each time. I want to copy the .so over and, with minimal additional code, be able to write:
import QQuickMapboxGL 1.0
at the top of my QML files and have it work.
Where do I need to copy the .so in my QML project, and how do I need to add it to the project so that the QML runtime can find it?
What I've tried:
Create a QQuickMapboxGL directory with libqmapboxgl.so in it.
Create a qmldir file in that directory with the contents:
plugin qmapboxgl
Add the following to my .pro file:
INSTALL_DIR = $$PWD/../install
target.path = $$INSTALL_DIR
# Copy the QQuickMapboxGL folder to the install directory
plugin.files = QQuickMapboxGL/*
plugin.path = $$INSTALL_DIR/QQuickMapboxGL
INSTALLS += target plugin
Add a make install build step.
The result of this mad hackery was:
plugin cannot be loaded for module "QQuickMapboxGL": Plugin verification data mismatch in '/my/build/QQuickMapboxGL/libqmapboxgl.so'
I have verified that the plugin and my application are both being compiled with the same version of g++ (g++-5 (Ubuntu 5.4.1-2ubuntu1~14.04) 5.4.1 20160904) and the same Qt download (5.7.0).
The main problem is that the .so is not a QML Plugin; no class inherits from QQmlExtensionPlugin or related. It is just a shared library of code.
Was able to workaround this by:
Adding the header files for MapboxGL to my project
In my main.cpp:
#include "3rdparty/mapbox-gl-native/platform/qt/include/qmapbox.hpp"
Calling QMapbox::registerTypes(); (inside main)
Copying libmapboxgl.so (built via Mapbox's make/cmake) inside a libs directory.
In myproject.pro adding: LIBS += -L./libs -lqmapboxgl
In my QML code import QQuickMapboxGL 1.0 and then using MapboxMap
Copying libmapboxgl.so to somewhere that is referenced by LD_LIBRARY_PATH

How can I organize files under the qml.qrc folder in Qt Creator?

If I have a bunch of resources (images, fonts, etc.) in different folders under my qml.qrc file, is there a way to organize this within Qt Creator?
For example, if I have the following in my qml.qrc file:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>pages/MainPage.qml</file>
<file>pages/NewContactPage.qml</file>
<file>images/plus.png</file>
<file>images/minus.png</file>
<file>images/exit.png</file>
</qresource>
</RCC>
It will show up as a long list in Qt Creator, like this:
Resources
qml.qrc
/
main.qml
pages/MainPage.qml
pages/NewContactPage.qml
images/plus.png
images/minus.png
images/exit.png
Since this list can get really long over the duration of the project, it would be nice if these were organized better and split into folders like they are in my directory. Any ideas?
Actually, I'd highly recommend that non .qml assets to be put in a different resource file altogether, because large files will gut application build times. What happens is even a tiny change to a qml source will result in recompilation of the entire resource file. If assets are in a different resource file they are not continuously recompiled.
This will also effectively achieve organization in addition to significantly improving build times.
I just discovered an awesome way to do it. What's weird is that nobody else suggested it, when it's so completely trivial. Perhaps it didn't work in old versions of Qt/Qt Creator but now it does.
Here it is:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>test/test.txt</file>
</qresource>
</RCC>
The test dir needs to exist and needs to contain test.txt.
No need for creating separate <qresource> tags with different prefixes. No need for alias attributes.
The files are cleanly organized in the filesystem and in the project explorer and you can access them from code with clean paths like :/test/test.txt.
(this screenshot is of a project that has some extra files as well - ignore those)
Bonus: You can rightclick on the "test" folder in the project explorer in Qt Creator and choose "Add new...", this does put the newly created file in the right place in the filesystem. Unfortunately it doesn't appear in the qrc subtree in the project explorer, only in a separate "Other files" subtree. You need to rightclick "qrc.qml" in the project explorer and choose "Add existing files" to make the file appear in the qrc subtree like it should. So it's a bit buggy/messy but when you learn how to use it, it's workable.
Bonus 2: You can import (add) an existing file/dir (which reside in any (sub-)sub-dir of the qrc file) and the right XML syntax will be generated, resulting in the right tree structure in the project explorer.
What I think doesn't work well:
Creating a file from Qt Creator from File -> New file or project (or Ctrl-N). This doesn't let you put the file in an arbitrary dir in the filesystem, only in the root project dir.
Files that you've put in subdirs aren't included in Qt Creator's project-wide search (Ctrl+Shift+F).
Edit: I just noticed the OP is doing exactly what I suggest. In that case, he probably is using an older Qt Creator version. Mine is 4.1.0.
If you want to use qrc files but don't like paths like "images/icons/images/icons/icon.png/" use alias as described here
<qresource prefix="/images">
<file alias="cut.png">images/cut.png</file>
</qresource>
With alias you can use your file by neatly writing /images/cut-img.png instead of /images/images/cut.png
From the Qt documentation: The Qt Resource System
By default, resources are accessible in the application under the same file name as they have in the source tree, with a :/ prefix, or by a URL with a qrc scheme.
It is also possible to specify a path prefix for all files in the .qrc file using the qresource tag's prefix attribute:
this example show how to do it:
<RCC>
<qresource prefix="/pages">
<file >pages/MainPage.qml</file>
</qresource>
<qresource prefix="/images">
<file >images/plus.png</file>
</qresource>
</RCC>
Another nice way to view your project files / folders as they appear on your File System is to do this:
Open your project
Click on the drop down menu which is above your project name, as demonstrated in the image below:
Done, now you can see your files and folders as they appear on your FS

Configuring Qt builds with Jenkins

I have several Qt projects that are dependent upon a Qt library that I've developed.
The project files (.pro) for projects which use the library define the LIBS and PRE_TARGETDEPS paths. For example: -
PRE_TARGETDEPS += ../ProjectLibrary_Qt_5_2_1_clang_64bit-Debug/projectlibrary.dylib
LIBS += -L../ProjectLibrary_Qt_5_2_1_clang_64bit-Debug -lProjectLibrary
As you can see, there is a defined path to the linked library and they have been building with Shadow Builds, via Qt Creator. The file hierarchy is like this: -
Projects
ProjectLibrary_Qt_5_2_1_clang_64bit-Debug
ProjectLib.dylib (the built library)
DependentProject
DependentProject.pro
(dylib is an OSX extension, but it could equally be .lib for Windows, or .so for linux)
However, Jenkins creates a different folder structure:-
jobs
ProjectLib
workspace
Project.dylib
DependentProject
workspace
DependentProject.pro
Now there is an extra directory (workspace), which would need this reflected in the .pro file and the names of the folders are different.
Obviously, If I just call qmake on the .pro with a Jenkins build, the path to the library is going to be wrong.
So, do I need to create a separate .pro just to be able to reflect the paths when building with Jenkins, or is there another way to handle specifying the location of libraries in the project file, for Jenkins, without having to change the directory structures?
Solution 1) Based on your current build configration
Modify your .pro file like this :
isEmpty(PROJECT_PATH) {
PROJECT_PATH=../ProjectLibrary_Qt_5_2_1_clang_64bit-Debug
}
LIBS += -L$${PROJECT_PATH} -lProjectLibrary
Then in Jenkins , you should pass PROJECT_PATH={path to your project} to qmake
Solution 2)
Using git submodule to fetch ProjectLibrary as a part of your building project. Then you don't need to build the ProjectLibrary by Qt Creator manually.

Qt: mingw compiled library does only work with both library.so and library.lib file present

I compiled a library using the MinGW toolchain provided with Qt 5.0.2 on Windows. As a result I received a library.so file. First I failed using the library in a Qt application, but now I found out that everything works fine when I make a copy of the liblibrary.so file and call it liblibrary.dll or liblibrary.lib (which is the only file ending supported by the add library wizard in QtCreator).
Now I wonder if this is normal or if I should change something in order not to have both files (which are exact copies). Leaving one away makes the application crash during start up. I added the library as follows to my Qt pro file:
LIBS += -L"../path/to/library" -llibrary
INCLUDEPATH += $$quote(../path/to/library)
EDIT: I compiled the library using the MinGW of Qt, not as Qt project but using mingw32-make and the provided Makefile. As a result I get the liblibrary.so.
EDIT: It seems to work also when renaming the copy to liblibrary.dll instead of .lib. But still, I need two files to make the application work -- the .so and the .dll.
Chris
That's weird, I think you should get a *.a and *.dll files when building a shared lib with MinGW on Windows, as said in the documentation:
In windows, MinGW will output .a and .dll, MSVC2010 will ouput .lib and .dll. In linux, MinGW will output .so, .so.1, .so.1.0 and .so.1.0.0 – .lib, .a and .so are import libraries.
You definitely shouldn't rename your file!
Be careful to:
not to include the "lib" prefix after "-l" in your project file.
put everything after after "-l" in lower case as you're on Windows
not adding any extension to your library name after "-l"
add and reference the .h file used in your library
A real example using QtWebsocket lib:
INCLUDEPATH += "$${PWD}/include/"
LIBS += -L"$${PWD}/libs/" -lqtwebsocket
...
HEADERS += ... \
$${PWD}/include/QWsSocket.h \
...
In my include/ folder, I have the following file:
QWsSocket.h (taken from original project - required)
In my libs/ folder, I have the following file:
libQtWebsocket.a
QtWebsocket.dll
Edit: I struggled with this too initially. Have you tried to build your lib as a static lib instead (CONFIG += staticlib in your library project)? This might help you getting you *.pro file right before switching to using the shared library.
Edit 2: Ok, the fact that you get a *.so file is still a bit odd. In this question
the user has the same issue as you and keep both files, which is just a workaround. According to a later answer it seems that you need to modify your makefile to generate a file with the proper extension. Maybe this will help: http://www.mingw.org/wiki/sampleDLL

Resources