Theming Qt for fun and profit

This feels great. This post is an eight year old dream come true – I have always wanted to write an article titled “… for fun and profit” ever since I read the amazing phrack article :) .

Qt Style Sheets makes it possible to style Qt widgets, we all know that. But, what if some user loved this Qt application and would love it even more, if only it had red push buttons (some users have strange fetishes)?

Qt 4.3′s well kept secret
In Qt 4.3, users can customize the style of any application without touching or recompiling the code. All Qt applications can take an external stylesheet using the -stylesheet command line switch. So, create a file called mystyle.qss containing “QPushButton { background: red; }”. Now start, any Qt applications as “qtapp -stylesheet mystyle.qss”. Sweeeet.

Theming Qt
So one can style widgets, but what if one wants to move things around. What if one wants the application to have a completely different layout. We have received many requests for supporting layouting in Qt Style Sheets, but did you know theming Qt applications is already possible?

So let’s see – we need a mechanism for the user to specify the layout. We can probably define our own XML format but it turns out Qt already has one and you use it all the time – .ui files. .ui file is nothing but the user interface described in XML. All we need is a mechanism to load these ui files on the fly.

Enter our hero QUiLoader. QUiLoader reads a ui file and gives you back a QWidget pointer. Ui files can be edited using Qt Designer, so you don’t need to create your own layout tool. In addition, QUiLoader::setWorkingDirectory allows creating ui files with external resources. That said, the main disadvantage is that theming this way requires you to modify your application.

I cooked up a media player that implements the above idea. You can add new themes in the themes/ folder. In addition to a layout(ui) file, the theme can also specify a style sheet. MediaPlayer can load these new themes with no recompilation.

Here’s the Classic theme that has the media controls on the bottom.
Classic Media Player

Here’s the Modern theme that has the media controls on the side.
Modern Media Player

To create a new theme,
* Unpack the source (with git history)
* qmake && make
* cp -R themes/classic themes/mytheme. At this point, mytheme and classic are identical.
* Edit file in mytheme/mediaplayer.ui using Designer
* Edit style sheet in mytheme/mediaplayer.qss using text editor
* Edit icons (play/stop/pause) under mytheme/.
* Notice how media player can support new layouts and styles with no recompilation at all.


P.S: This is really a guest blog since I don’t work for Trolltech anymore :-) Please contact me at ramakrishnan dot girish at gmail, if you have any questions.