Console Applications in Qt
I recently had to produce a console application and chose the Qt toolkit to write the application in. I can hear the shocked replies now, “isn’t Qt a graphics toolkit?”, “why bother?”, “how?”, “are you saying we should all use Qt?”, and “what has this got to do with professional programming?”
I’ll address each question in turn.
Isn’t Qt A Graphics Toolkit?
Indeed, Qt was born and bred a widget library for writing graphical applications.
However, even from its early days Qt has offered three strong features of interest to writers of console applications:
- Qt has its own classes for strings, maps, lists, and just about everything in the Standard Template Library, only in my opinion done neater.
- Qt’s classes extend beyond the STL to XML, network wrangling and more. “SOAP” is a big buzzword for people writing code to interface with Microsoft applications at the moment, and Qt has made XML network interfaces pretty easy since before the buzzword existed.
- Qt is portable to a wide range of platforms.
With the release of Qt4, there’s another feature to add to that list:
- You can compile against just the “core” parts of Qt, and not compile in all the graphical abilities if you don’t need them.
Qt has been organized into modules, such as “core” (with the STL-like functionality and internationalization), “xml”, “network”, and now the “gui” is just a module like all the others.
When I read about that change it prompted me to download the latest Qt and have a go at using it in writing my console application.
Why Bother With Qt?
Qt is portable to a range of platforms and has been written in a way that makes common tasks easy and just about any task possible. It offers very neat solutions to things like deleting objects when they are no longer needed, and to iterating over all of a list, but it doesn’t force you to use those solutions if the model they’ve chosen doesn’t suit what you’re trying to achieve.
I find the implementations of Qt objects far neater and better organized than the STL equivalents. And if you’re not familiar with the STL then you may have missed another important feature: strings, lists, maps etc are not only trivial to implement but can be thrown around as easily as integers can. You generally don’t need to worry about pointer management etc. A function can return a list of strings and it’s really just returning a structure that points to the real data using reference counting to delete the data when its no longer used by your program. This means that you can write your code to look elegant and simple, and trust Qt to keep it fast and efficient. You save on a lot of debugging that way.
How To Write Console Apps In Qt
A traditional graphical Qt application looks much the same as any other event driven program: Initialize stuff, then call an event loop to do the event handling. Here’s a snippet from their own “fortune client” example:
#include <QApplication>
#include "client.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Client client;
client.show();
return client.exec();
}
This initializes the application, creates a “client” object, calls the function to show the graphical window for this object, and then runs exec(), the main event loop for the client.
Note that exec() can be run on either the application or on a dialog window. In this application the dialog window was chosen to make it a “modal” dialog, preventing events from being processed by other parts of the application while the dialog is active.
Now, let’s adapt this for a console application:
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv[]);
// (1) We *could* write a whole application
// here if it doesn't need event handling.
// (2) Set up something that will trigger events
return app.exec();
}
Now we have a console application. If you just run it as-is, the event loop will run forever. You need to think about whether your console application requires event handling.
If it does require event handling, for example if it’s some kind of server application that receives network events, then you need to set up the networking system and connect any events you want handled at position (2).
If you don’t need event handling, I prefer to still run the event loop at the end of the program, just in case something in the program posts an event to clean itself up. If you simply use “return” without ever running the event loop it works fine, but I like to be cautious:
// (2) Set up something that will trigger events
QTimer::singleShot(0, &app, SLOT(quit()));
This adds an event to the end of the event queue that will quit the program, and runs the event processing.
Whether you use event processing or not, it’s safe at point (1) to use all the Qt features that aren’t event driven, including the STL-like features, basic XML features, etc. If it doesn’t rely on something responding to a “signal” then it doesn’t need the event loop making those signals execute.
Should We All Use Qt?
Qt isn’t for everyone. As always I recommend you look around and learn what’s out there. I’m offering my experience with Qt as just one more piece of “what’s out there” for you to use or not use, but either way to learn from. Perhaps it will raise your expectations of a different toolkit, and start you digging through the manuals to see if it can do the same things.
As with any library, make sure you read the license agreement. Qt is available under both “strict” GPL and by commercial license. This is clever because it means if you’re writing open source applications under the GPL then you can use Qt for free, but if you’re making a buck then Trolltech wants some money too. It’s a clever arrangement that matches my ideals rather well, but might not match what you’re trying to do.
What Qt Says About Professional Programming
I consider Qt to be a great example of professional code for several reasons:
- Qt is portable. Code that only runs on one kind of system really limits your potential customer base. It also makes it harder for you to keep up with updated versions of the system you’ve chosen.
- Qt is consistent. With each new version Trolltech have tried to make the function calls even more consistent, so you don’t need to remember “this gadget behaves a little different”: if the functionality is there it will be called the same thing and work the same way as you are used to from other parts of Qt.
- Qt makes common things easy. Making something flexible requires a fair bit of work, but if there’s something you do thousands of times over in every program then it should be as simple and as clear as possible. Well chosen default parameters and macros like “foreach” to loop over every element of a list/map/vector help a lot with making the common tasks as easy as possible.
- Qt is modular. You can choose which set of features you need and not compile in extra unwanted features.
- Qt doesn’t assume it’s the only library. This is something we can
all learn from:
- All its symbol names are both in a namespace and follow a naming convention where everything starts with the letter “Q” to avoid symbol names matching those from other libraries.
- Qt reads and writes to the most basic data structures very readily, for example by calling an “int” an “int” (rather than an x-coord-type or whatever), and by converting strings to and from “char*” style strings and STL strings so you can send them to other libraries whenever you need to.
At the LinuxConf 2001 conference I went to a talk by Sirtaj Singh Kang about what was learned during the production of KDE. KDE is a Qt based desktop environment and applications platform. Singh commented that one of the main things they’ve learned in writing KDE was to write every application as a library from the start, because you never know when your text editor will become a useful component inside a web browser, or your web browser a component to view email messages.
As well as being a good example of a library, Qt makes it very easy to write your own applications as libraries, following this model that hard experience has shown to be so valuable.
References:
- Trolltech Qt
- K Desktop Environment (KDE)
- Qt Fortune Client Example
- Why KDE Works, presented at LinuxConf 2001 by Sirtaj Singh Kang.
Disclosure: My brother works for Trolltech, and although I liked Qt before he started working there it is important to evaluate Qt and many other toolkits for yourself before deciding which toolkits are best for you.
2 Comments
Please use the DP Forums for further discussion of this topic.



Of all the good that people say about QT I have spent the whole day without finding a way of getting a key from the standard input in a QCoreApplication. And the sentence has been cleaned up not to offend anyone.
Does anyone has an idea or an hammer?
thanks
Comment by Alberto — On 7-9-2006 at 12:18:01 AM
QtCore lets you use the features Qt offers without the full GUI but it doesn’t provide much “instead” of the GUI. For console apps if you need keystrokes I’d be looking at libcurses or similar.
Comment by sarah — On 12-10-2006 at 11:11:07 AM