In case you’ve been living under a rock or something and haven’t heard about Qt, it’s a cross-platform application framework that’s most famously known for being the underlying widget toolkit for the KDE desktop environment for *nixes.
Prior to a couple weeks ago I had never played with Qt, and I actually had sort of a negative opinion of it. I had known that it required this extra compilation step where it preprocessed C++ source files for some reason… but I’ll back get to that soon — for now I’ll just say I thought it was silly because I didn’t understand it. The other thing I thought was that Qt was just a widget toolkit for building GUI applications.
I was wrong. On both accounts. First of all Qt is so much more than just a GUI API. It’s an amazingly well designed collection of classes for building robust cross-platform apps. Example, the QString class is so much more useful than std::string. It has built in support for all types of unicode strings, and has a ton of handy functions and operators available. Memory management is also really well done in Qt — you can often “new and forget”. It has a high performance computing API that includes out of the box support for things like Map-Reduce, job scheduling, futures, etc. I could go on and on, but suffice to say, Qt is another tool I’m really glad to put into my toolbox right next to Boost.
As a quick aside, before getting to my actual point, I’d like to mention Nokia’s recent acquisition of Trolltech (the company responsible for Qt), and their decision to LGPL the library. I think that this is probably the greatest thing that has happened to Linux, since the Linux kernel itself, and perhaps the GNU tool collection. I honestly can’t see why any developer would continue to support and use Gnome now that Qt is LGPL’ed, and you can use it to write cross-platform apps that use native widgets on Mac, Windows, and Linux. Competition is usually good, but not when it comes to competing desktop widget sets.
Alright, my actual point, and the thing that inspired me to post about Qt in the first place: the MOC. Qt’s Meta Object compiler. What it does is preprocess a C++ header and build another header out of it that you then include into your source file along side the original header. This preprocessing step gleans all of the information from your class(es) and puts it into a format digestible at runtime. Qt has kindly wrapped this up into a nice meta object system that stems from the QMetaObject.
Essentially what they’ve done is given reflection to C++. If you’ve ever programmed in languages like Python, Ruby, Objective-C, C#, or Java, and friends, you know how awesome and useful reflection is. With Qt’s MOC system you can do many of the neat things in C++ that you can in dynamically bound languages. You can enumerate all the methods of a class, and then invoke them via a string representation of their function name. You can dynamically cast to and from super-classes (again, via a string), or iterate over an object’s class hierarchy — all at runtime! It’s awesome. Really awesome.
But, does this extra MOC step require some insane build system? Well, fortunately no! Thanks to the KDE project having adopted CMake as their build system they’ve created all the necessary build scripts for using Qt in your project. You just do your build setup like you normally would with CMake, include the Qt CMake module, which automatically detects the Qt libraries, and sets up support for automoc’ing your source files.
And while I’m on the topic I might as well say a few words about Qt as a GUI library. I’ve use quite a few GUI APIs in my day: everything from raw WIN32, to MFC, and .net’s WPF (Windows Forms), Cocoa and Carbon, WxWidgets, GTK, TK, AWT, Swing, and there’s probably a few others in there that I’ve [likely thankfully] forgotten [or repressed].
In the past, I’ve never really been impressed by a GUI API before. Cocoa is the one I’ve used the least, but I was definitely impressed by it — that being said it’s sort of wrapped up in the Objective-C way of doing things, which isn’t necessarily bad, but it’s a bit more difficult to evaluate on its own because of that fact. Windows Forms is also relatively well done, but nothing to write home about. And the rest are just plain awful. With the shining star being Qt.
When I created my first Qt GUI (through the help of Qt’s excellent GUI designer) I was extremely happy. I’ll be the first to admit that I hate GUI programming, but let’s face it, every once in a while you do need an app with a GUI, and Qt takes all the crap work out of GUI programming. There’s almost never a need to write code that resizes widgets when you resize your application’s window (they have a well thought out Layout system), and the whole process of designing a GUI and including it in your app is very well done.
The GUI designer creates a nice human readable XML file that you can either have your CMake build system auto-process for you and produce C++ code that you merely include into your project, or you can use the Qt library to dynamically load and process the UI XML files at runtime. Who doesn’t want their users to be able to change your GUI around in whatever twisted ways they want? Well okay, probably a lot of people, but at least the option is there!
All in all I give Qt a resounding thumbs up. I will probably use it in every spare-time project I do from now on, even non-graphical ones, just because I think the API is that good — Qt really has given C++ a gift with their meta-object system. And now with Nokia’s support and LGPL goodness, there’s finally no reason not to use Qt.











