Qt Resource Files don't update without compiling - c++

I am making a C++ application, and I created a function that will apply a stylesheet from a css file. This is the method:
void MainWindow::load_css_file() {
QFile styleFile(":/light_style_css");
styleFile.open(QFile::ReadOnly);
QString styleSheet = styleFile.readAll();
setStyleSheet(styleSheet);
};
This works fine, except for the fact that I need to run "make" every time I make a change to "light_style_css" (which is an alias for a css file in my project resource file).
But, when I change the method to something like this:
void MainWindow::load_css_file() {
QFile styleFile("../stylesheets/light_style.css");
styleFile.open(QFile::ReadOnly);
QString styleSheet = styleFile.readAll();
setStyleSheet(styleSheet);
};
I can make changes to the file, and the program updates without having to run "make" for the changes to take place.
Is there a way, that I can use the resource system, without having to run "make" for the changes to take place?
This is my resource file:
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="light_style_css">stylesheets/light_style.css</file>
</qresource>
</RCC>

Simply said: no, you can't.
Resources are built into your executable. If you want to change them, you need to rebuild the executable.
Your second method reads the file from disk, so it doesn't have that behavior.
If this is a real problem for you, give the possibility to pass in the stylesheet as an argument on the command line, and default to the resource. That way you can debug the stylesheet as much as you want without recompiling every time. Rebuild once it's satisfactory (and before you ship!).

We do the following solution in our project (I can't provide code because of company policies):
First, we build all resources to separate binary .rcc file. It is not necessary, but helpful.
Second, In release builds we always load resources from the Qt resource system.
Third, only in debug builds:
We check the resource folder for a main.qss file.
If it exists: we open it and replace all :/ with ./resource/ string, then apply it
If it doesn't exist: we load resources as in the release version.

Related

Why does giving ":/Icons/controller.png" to a constructor work (is that valid relative filepath syntax)?

The details of the situation don't matter, but in particular I'm making a QIcon object (part of the Qt library) out of a .png file. The constructor for this takes a string that should be a filepath
I find that, instead of using an absolute path, I can simply give something like ":/Icons/controller.png" to the constructor and the icon is still correctly retrieved and displayed.
My project is huge so I won't write out the hierarchy and where the file is relative to everything else, but they're at 3 degrees of separation at least. Because of this I think there's some sort of file searching mechanic that I don't know of. Can anyone guess what's going on here?
:/ paths are paths in the Qt Resource System.
You have a QRC file that is compiled and bundled with your executable. It references the images.
E.g. your qrc file contains this:
<RCC version="1.0">
<qresource>
<file>Icons/controller.png</file>
</qresource>
</RCC>
This is then compiled in your build process with the RCC compiler. This file is then linked with your exe.
The default resources are automatically registered, but you can also compile resources into external RCC bundles, and load them at runtime using QResource::registerResource("/path/to/myresource.rcc");

QIODevice::write : device not open

I've been trying to build a card game using Qt recently, but I come across a bug which is very weird.
QFile file(":/file/02");
file.open(QIODevice::ReadWrite|QIODevice::Truncate);
The return value of the second line is false. So when I try to read or write the file, this exception is thrown.
However,the file actually exists and a qrc file in the project writes like this:
<qresource prefix="/file">
<file alias="01">data.json</file>
<file alias="02">deck.json</file>
I've also run qmake after adding this qrc file, but everything remains the same. How can I fix it? Thanks a lot.
According to the docs:
The Qt resource system is a platform-independent mechanism for storing
binary files in the application's executable. This is useful if your
application always needs a certain set of files (icons, translation
files, etc.) and you don't want to run the risk of losing the files.
As it is part of the resource, the files are read only, so if you open it with write permission it will always return false.
In short the files stored in .qrc are static.

WxWidgets - Unable to load images

I recently started working with WxWidgets (2.9.4) and was working through a tutorial I found, but it seems that I'm unable to load any images. I've already properly used the handler (for PNG) and the problem happens at run-time. Below is an image of the popup that is displayed when attempting to run the program.
Here is the code:
wxPNGHandler *handler = new wxPNGHandler;
wxImage::AddHandler(handler);
wxBitmap exit;
exit.LoadFile(wxT("exit.png"), wxBITMAP_TYPE_PNG);
wxToolBar *toolbar = CreateToolBar();
toolbar->AddTool(wxID_EXIT, exit, wxT("Exit"));
toolbar->Realize();
Connect(wxID_EXIT, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(mainWindow::exitProg));
Any help is appreciated.
EDIT: I forgot to mention that when I click Cancel, this happens:
I placed the exit.png file in the build directory (/Debug or /Release) as well as the source code directory, but it still has yet to see it.
What is your working directory?
If you are using visual studio and running using the interface ( F5 or ctrl-F5 or the little run button in the toolbar ) then your working directory is the folder containing the project file. So try copying your image file there.
Or open a command window, cd to one of your build directories, and run your app from the command line.
In general, to avoid this sort of problem, I alter the project properties so that the executable is NOT stored in one of the build folders, but in a new folder ( which I usually call 'bin' - my unix roots are showing! ) and also alter the debugging properties so that the working directory is the bin folder.
There are a couple of advantages to this technique:
Both the release and trhe debug version use the same folder, so you only need one copy of any extra file, like your image file.
It is easy to see the executable and extra files in the working directory without being distracted by all the .obj files that end up in the build folders
IMHO this is well worth the little extra trouble in maintaining non default project properties.
First of all, to avoid problems deep inside wxToolBar, always check the return code of LoadFile() or, alternatively, use wxBitmap::IsOk() to check that the bitmap was successfully loaded.
Second, while adding the handler explicitly as you did is perfectly fine, I'd recommend to just call wxInitAllImageHandlers() as it's simpler and has no real drawbacks unless you are looking to create the smallest program possible.
Finally, to address your real problem, the file clearly doesn't exist at the path you're loading it from. You can, of course, solve this by being careful not to change your working directly (or restore it after changing it) in your program and by placing the file in the correct place. But this is, as you discovered, error-prone, so a better idea is to always use full paths to your resources. To construct them, you will find wxStandardPaths useful, in particular its GetResourcesDir() method.

what dll to load if i want to see images when deploying in runtime, also which vc dll do i realy need?

i first time deployed my app outside of the visual studio compiler on clean pc .
and i have problem . first i dont see any images in my application
i use .png , *.gif,.ico file types i trying to add the :
qgif4.dll
qico4.dll
qjpeg4.dll
qjpeg4.lib
qmng4.dll
qsvg4.dll
the way im using my images is with *.qrc file and i was hoping it compile it as resource ( i really hope .. )
in the pro file i just added it like this:
RESOURCES += resources.qrc
and it looks like this:
<RCC>
<qresource prefix="/">
<file>images/image1.png</file>
<file>images/icon-loading.gif</file>
<file>images/filter.ico</file>
<file>images/icon_lp.png</file>
</qresource>
</RCC>
but with no good i still see blank instead of images .
also do i need one of the vs run times dll’s in my application?
msvcm90.dll
msvcp90.dll
msvcr90.dll
Thanks
The image plugins need to be in the right location for the Qt plugin loader to find them. Try putting them in an 'imageformats' directory next to your executable.
Use depedency walker to figure out which are the libraries linked to your application. This way put your application in a random directory, use the tool and you will see all missing references. these are the one you need to include.
Can you show the line of code where you use an image?

Qt Resource file utilization

Here i am describing the problem that i faced with Qt resource .rcc file.
first, When i created the .qrc file in my project it will fit all the resources that is added in the qrc, in to executable binary file.
second, rcc file in Qt used for well and optimize resource utilization and when i create it in my project it is still including all the resources (added in .qrc file) into the executable binary file even rcc file already contains all the resources so, my question is why to use this rcc even if resources are included in executable binary file. Why to include redundancy in project??
it may possible i misinterpret something or i am not aware of some points, please correct me if i wrong.
It's too late for answer, but may be helps anybody.
I've expected similar problem, and used next solution:
if you use QtCreator, just wrap your RESOURCES += xxx with config condition in .pro file, like that:
!realbuild {
RESOURCES += xxx.qrc
}
and set CONFIG+=realbuild to qmake params. What does it given? You may edit your forms with QtCreator's designer, and use resource directly from editor, but it will not be compiled into your target file, resources must be loaded in run-time using QResource::registerResource(). Use can build resources manually, using direct call to rcc tool, or write a simple script, and call it using QMAKE_POST_LINK variable.
Now question is - how to reload resources in run-time?...
There are two options for Qt resources:
include the .qrc in your .pro file with
RESOURCES = myapp.qrc
create an external binary resource file with rcc, then register it at runtime with
QResource::registerResource("/path/to/myresource.rcc");
Don't do both. i.e. if you previously had the .qrc directly included in your .pro, and now want to include it dynamically, remove the RESOURCES line from the project file and do a clean build. External binary resources are not included in your executable if you don't list them in the RESOURCES setting of your project.