How to rightly add resources in Qt application - qt

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")));

Related

How do I make my own directory in QT QML?

I'm trying to make a directory of a singleton QML File "All.qml" which I can import anywhere else into my project so that I can access its objects (namely the drawer). I made a qmldir file, in the same folder as the "All.qml", and even add the directory to the .qrc file.
The contents of the directory is as follows:
Module App.Drawer
singleton All 1.0 All.qml
But when I type in
import App.Drawer. 1.0
It says "module 'App.Drawer' not installed". I can't find any other way to access that drawer, as the project is huge with multiple folders and directories. Can anyone help me?
Also, this project has C++ integrated with it. I tried going and finding some file where maybe the other directories (there are other custom directories, which were made beforehand) have been installed, but couldn't find any.
You have to make sure that QEngine can find the qmldir file, and it has some specific requirements on where it will look.
First to make QEngine aware of the qmldir file you have to add an import path:
engine.addImportPath("qrc:/");
Your path may vary, read on:
The qmldir file has to placed in the folder structure dictated by module name. In your case it is <rootPath>/App/Drawer/qmldir. The "rootPath" is unknown to me, but let's assume you have the following in your qrc file:
<RCC>
<qresource prefix="/ProjectX/App/Drawer">
<file>Drawer.qml</file>
<file>qmldir</file>
</qresource>
</RCC>
Then "rootPath" is qrc:/ProjectX and the import call becomes:
engine.addImportPath("qrc:/ProjectX");
Also, the module declaration in qmldir should be the same as the folder structure where the qmldir file is placed. (And I think it should be lowercase)
module App.Drawer
singleton Drawer 1.0 Drawer.qml
If you want Qt Creator to also find the stuff you can use the QML2_IMPORT_PATH environment variable and set it to the correct folder using the same logic.
You can also place the files in the <Qt_installation_folder>/qml/App/Drawer but this means every project can use it and you have to keep it up-to-date during development, which might be overdone.
Edit
To see if your files are lined up correctly, you can add this debug code:
QDirIterator it(":", QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << it.next();
}

In Qt, use resources not located in the source directory

I need to use a set of resources from several different programs (images, fonts, txt files, etc). So I put them in a common folder. So I try to read one of these txt files using this path:
":/../../CommonClasses/PNGWriter/report_text/English"
However this does not work as the the QFile cannot be opened for reading with this path.
Hoewever if I move the report_text directory to the source directory and use this path:
":/report_text/English"
Then it all works just fine.
So my question is, is it possible to user resources not located in the source directory?
EDIT:
Here is my .qrc source file (and I replaced stuff.txt with an actual file from my resource file)
<RCC>
<qresource prefix="/">
<file>../../CommonClasses/PNGWriter/report_text/English</file>
<file>../../CommonClasses/PNGWriter/report_text/GothamBlackRegular.otf</file>
<file>../../CommonClasses/PNGWriter/report_text/GothamBold.otf</file>
<file>../../CommonClasses/PNGWriter/report_text/GothamBook.otf</file>
<file>../../CommonClasses/PNGWriter/report_text/GothamLight.otf</file>
<file>../../CommonClasses/PNGWriter/report_text/GothamMedium.otf</file>
<file>../../CommonClasses/PNGWriter/report_text/Spanish</file>
<file>../../CommonClasses/PNGWriter/report_text/viewmind.png</file>
</qresource>
</RCC>
The alias keyword is useful for giving things a different name in the resource system.
Instead of
<file>../../CommonClasses/PNGWriter/report_text/viewmind.png</file>
you'd write
<file alias="report_text/viewmind.png">../../CommonClasses/PNGWriter/report_text/viewmind.png</file>
Of course, this is bit of a pain if you're manually maintaining large qrc files; it may be useful to automate (script) production of them.
Thank to the friendly tip #timday, I've managed to see what the problem is. The ../../ that I used were the problem. The path to the file was actually:
:/CommonClasses/PNGWriter/report_text/English
Now it works just as expected!! I hope this helps anyone else with this problem!
I don't believe this is a native option, as when I try to add files above the project sub-directory I get "The file "/path/to/file/" is not in a subdirectory of the resource file. You now have the option to copy this file to a valid location.", with the copy option.
However, (if on linux) adding a symbolic link to the resource file in the project subdirectory works perfectly fine for me. So something like ln -s /path/to/target/resource /path/to/project/directory/resource_name.file, and then adding resource_name.file to your resources file should work. It does on mine (Qt 5.7).

Creating a Qt install package with InnoSetup : missing images

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.

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

How to replace qt.conf?

I'm working on an embedded system. The directory /root/txpa/images/current/application/bin contains the file qt.conf, the content of which looks like this:
[Paths]
Prefix=/qtdir
Libraries=/qtdir/lib
/qtdir/lib/fonts is about the only thing in the path, and it contains several fonts of kind Vera. These are the only fonts in the system, and the app itself doesn't use them directly. Qt does.
I've been asked to remove qt.conf from its current directory, but if I do the app doesn't start (I suppose Qt can't find any fonts). How would i do this? I've read about Qt resource system, but I'm not sure how to go about doing this.
These are the steps I had to follow in order to resolve this problem:
First, create a qt_conf.qrc file that looks like this:
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/qt/etc/">
<file>qt.conf</file>
</qresource>
</RCC>
QLibraryInfo will load qt.conf from :/qt/etc/qt.conf using the resource system. That should explain the above qt_conf.qrc.
Second, copy the qt.conf file to the same directory as the qt_conf.qrc file (this can be changed, of course).
And finally, update the *.pro files, if any, and rebuild. The original qt.conf file can be removed from the directory that it was in.

Resources