Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle large Qt resource files on a system with a very slow storage?

Tags:

c++

qt

An embedded system has the hardware required to run Qt Quick applications, has a nice CPU and good GPU, but has an extremely slow non-volatile memory.

As the GUI has a lot of images, I have the following dilemma:

  • if I put the images into a qrc file, it will be compiled into the executable, so the application will load very slowly.
  • if I load the images as normal files on-demand (not all of them are visible in every menu and dialog), the program will hang for a while whenever such a menu or dialog opens, waiting for the images to be loaded from flash memory.
  • Managing the individual images manually (for example, in a manually written background thread) seems like too much effort, so I hope there is a more elegant solution.

Is there a nice way to use the Qt resource management system to load the resources in the background? The images used in the main GUI should be loaded while a splash screen displays a nice progress bar, and the rest can be loaded silently in the background after the main application starts. A nice addition would be if I could selectively load and free up certain resource files (in some states of the application some resource files are not needed, so it would be nice if I could free up some memory)

Is there an elegant way to solve this with the Qt resource system, or do I have to manage all my images manually?

like image 809
vsz Avatar asked Mar 21 '16 10:03

vsz


2 Answers

It seems to be helpful to mentioning some notes (in my experience):

  • Resource images which will be used as interface resources (such as icons), should be embedded in default qrc resource file. They should have small size.
  • Some resource files are large and will not be loaded frequently. These resources can be loaded dynamically as external files.
  • You should load asynchronously large images (using asynchronous property).
  • You should use Loader element for loading large/complex components.
  • You can use UX solutions/tricks to making delay invisible (like showing progress bars, playing micro-animations, transitions,...).
  • As I researched some hours, it seems to be helpful to use dynamic resource files (rcc files) with/without compression for large resources OR use native file system.
like image 71
S.M.Mousavi Avatar answered Sep 22 '22 04:09

S.M.Mousavi


So you don't want resources embedded into the application, because that bloats the executable and it is too slow to load, and you don't want resources outside the application, because they are too slow to load?

First of all, being a resource in the executable doesn't mean you are an object ready to use in memory. In most cases you will still have to load that data into a Qt object, for example an image file into a QImage. You will still get that delay. And unless that part of the data is paged in memory, it won't be any faster than reading from disk directly.

The best and pretty much only thing you can do is mask the delay out. This is only possible if you know which resources are needed for each application state, and every time you change a state you load all the data needed for states you can get into from the current state. This way resources will be loaded ahead of time, and hopefully before you get to the new state requiring then. The downside - you will have to keep tracking those objects and you will have memory overheads - as you could possibly be loading data for more than one states but enter only one. The upside - most of the loading can be hidden from the user, and you only preload a subset of the entire data, not all the data. Naturally, reducing the footprint of the resources as much as possible is a must.

Other than that, there isn't much you can do. If your storage is slow, the best solution is to upgrade it if you can, second best - be realistic about what you can expect from the hardware.

like image 24
dtech Avatar answered Sep 24 '22 04:09

dtech