Aurélien Gâteau wrote:
Hello,
Cobranding work is going well, the configuration part is done, you can now
define your own default configuration values by editing the
system 'config.xml' file instead of editing config.cpp.
I am now working on loading images from the file system instead of bundling
them in the binary, using resource files defined in .qrc files.
A .qrc file contains a list of files, it is processed by the resource compiler
('rcc') to produce a C++ file containing the content of all the files. This
C++ file is then compiled and linked in the binary.
My initial proposal to load images from the file system was to introduce an
ImageLoader class which would centralize all image loading code, and replace
all occurrence of:
QPixmap(":/pics/some/image.png")
with:
ImageLoader::loadPixmap("some/image.png")
It was going well, until I hit the .ui wall: To assign images to widgets in
Designer, one need to choose a .qrc file, then select images from this .qrc
file to use in widgets. The .ui compiler ('uic') will generate code for
this .ui, loading images in the QPixmap(":/pics/some/image.png") way.
One solution is to give up defining images from Designer and do it from the
code, but it means lots of empty widgets in the .ui file, so I think it would
be quite of a regression.
Another solution, which I am submitting to you for your opinion, is to trick
Qt into loading images from the file system. To load resource files Qt
implements a resource file engine by inheriting from QAbstractFileEngine [1].
Qt resource file engine handles all file names beginning with a ':'.
What I did is to register another file engine which handle file names
beginning with a ':' *before* the Qt resource file engine.
Implementation is really simple, it's not even a custom file engine, it just
reuses the QFSFileEngine class:
---
#include <QtCore/QFSFileEngine>
class FSResourceFileEngineHandler : public QAbstractFileEngineHandler {
public:
FSResourceFileEngineHandler(const QString& baseDir)
: _baseDir(baseDir) {}
QAbstractFileEngine* create(const QString& path_) const {
QString path = path_;
if (path.size() > 0 && path.startsWith(QLatin1Char(':'))) {
path = _baseDir + path.mid(1);
if (QFile::exists(path)) {
QFSFileEngine* engine = new QFSFileEngine;
engine->setFileName(path);
return engine;
}
}
return 0;
}
private:
QString _baseDir;
};
---
To use it, declare the handler in the main() function, like this:
---
int main() {
FSResourceFileEngineHandler handler("/path/to/resources/");
...
}
---
Now, make sure "/path/to/resources" contains the files defined in your .qrc
file and you're done. This code:
QPixmap pix(":/pics/image.png");
Will make Qt load the pixmap from /path/to/resources/pics/image.png
The nice thing about this is that if there is no file matching the requested
filename in the file system, FSResourceFileEngineHandler::create() returns 0,
and Qt fallbacks to its own resource file engine.
From within Designer you can still use .qrc files, and select images as
before, but the .qrc file does not need to be compiled anymore.
It's a bit tricky because one must declare the handler *after* Qt resource
handler. In this case it works because Qt resource handler is defined as a
static global variable, so it's initialized before entering the main()
function.
Another advantage of this solution is that it requires very little changes,
compared to the ImageLoader solution.
What do you think about this idea?
Aurélien
[1]: http://doc.trolltech.com/4.1/qfsfileengine.html
_______________________________________________
Wengophone-devel mailing list
Wengophone-devel@lists.openwengo.com
http://dev.openwengo.com/mailman/listinfo/wengophone-devel
It is pretty clever tric,
But did you consider, adding small sed script into build sequence
replacing QPixmap() with
ImageLoader::loadPixmap("some/image.png")
or
with OWQPixmap?
Thanks
Vadim
_______________________________________________
Wengophone-devel mailing list
Wengophone-devel@lists.openwengo.com
http://dev.openwengo.com/mailman/listinfo/wengophone-devel