In Qt, use resources not located in the source directory - qt

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).

Related

Where to deploy external resources/files?

within my Qt5 application a file ":items/cube.obj" is accessed (.obj is a 3D format and this comes from a piece of example code).
Where within my project/Qt installation path do I have to deploy this file "cube.obj" to let it work with this funny path name?
Thanks!
From docs:
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.
Note: forward slash in :/.
If you don't use prefix in .qrc, it would be in items directory next to .pro:
/path/to/project/myproject.pro
/path/to/project/items/cube.obj
In this case root prefix is used.
If using non-root prefix, .qrc could be:
<qresource prefix="/items">
<file>cube.obj</file>
</qresource>
and files structure:
/path/to/project/myproject.pro
/path/to/project/cube.obj
Using alias:
<qresource prefix="/items">
<file alias="cube.obj">items/cube.obj</file>
</qresource>
and files structure:
/path/to/project/myproject.pro
/path/to/project/items/cube.obj

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 add files in the RPM package of an Sailfish OS project?

I am trying to build a Sailfish OS app, and I need to use *.wav files, which are to be distributed through the *.rpm package. In my case, these files are to be put in /usr/share/[application_name]/sounds/*. How do I set up the *.pro and *.yamp files accordingly?
This isn't a RPM question per se: you seem to be asking how to configure
your application through *.pro and *.yamp if you deliver content in
*.rpm packages.
The packaging answer is: Patch the configuration files exactly the same
as if you were installing the *.wav files manually (i.e. not through *.rpm).
You will need to copy the *.wav content into the %buildroot tree that
is used to stage the files to be included in the package, as well as the
modified *.pro and *.yamp content. All the files to be included in the
*.rpm package will need to be mentioned in the %files manifest exactly
as they are to be installed (i.e. w/o the %buildroot prefix used for
staging files while building).
I finally found an answer!
I want to thank to the owner of that project:
https://github.com/krig/metronom-sailfish
From the .pro and the .yaml files of this project i found out how to deploy the files. First, we declare that constant:DEPLOYMENT_PATH = /usr/share/$${TARGET} which seems to hold the path to /usr/share/[appname]. Next, we define some kind of a variable (TODO: find a more detailed explanation of that). The definition of that first sets the path to the files, for example, data.files = data (the second data is the folder). Next, we set data.path to $${DEPLOYMENT_PATH}. We list all the files in OTHER_FILES and add the setting, in our case, data, to INSTALLS. Now, that we are finished with the .pro file, we move to the .yaml file for the .rpm and we add to the necessary line to the Files: section, in our case, - '%{_datadir}/%{name}/data', the last being the folder we need to add. TODO: to whoever is more experienced, please provide a more detailed answer.
Did you check https://sailfishos.org/develop-packaging-apps.html carefully? May helps.

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.

How do I create a jar file, which includes xml and html files?

I am trying to create a jar file which includes some class and java files needed, but I also would like to include some extra xml, xsl, html, txt (README) files.
I am using Eclipse on Windows XP.
Is there an easy way for me to set up a directory structure and package all my files into a jar?
Add the files to a source folder and they can be included in the jar.
One common way is to have, at the root of your project, a src folder. Within that, folders for java files, and others. something like:
src/
css/
java/
html/
images/
Then you can make each of those subfolders a source folder (Right click, Use as Source Folder) and they should be available to add to the jar.
A .jar is nothing but a ZIP archive, so you can use any program capable of creating ZIPs. Just make sure that you include the manifest and all the class files.
I just added all the files into my Eclipse project (including the txt, html, xml, etc files).
Then I used Eclipse to File->Export->Jar File->Next
Check the "Export Java source files and resources" box.
Done.
If you're using Ant, you can use the jar task (see the examples section for how to include/exclude certain files, etc.)
If you move to an ANT (or Maven, for you Maven fans) then you can automate the Jar building very nicely, and also use it outside of Eclipse (e.g., in an automated build environment). All you need to do is copy the files from your src, jsp, foobar and resources locations into a build staging folder, then Jar the resulting files using ANT's Jar task.
<target name="makejar" depends="compile, copyfiles">
<jar destfile="${jars.dir}/myjarfile.jar" index="true" basedir="${build.dir}" />
</target>
One thing I look down on is including non-source (except package.html files for Javadoc) within the src folder. If you feel you have to do this to achieve something, then you are doing it wrong.

Resources