Benefits of the Qt Object Model

Qt is known as a cross-platform graphical user interface toolkit. It
is that, but it's also a toolkit for dealing with databases, file
access, sockets, and much more. This article concerns the Qt object
model and why it is an improvement over the classic C++ model.

The Qt Object Model

The classic C++ object model has data and methods which can be either
private, protected, or public. When designing a GUI (or any other
event-driven task), we want to tie a method implemented by us to a
specific event. To do this, we inherit the event-generating class,
overload the virtual method, and re-implement it to do what we want it
to do. This gives us two problems:

We will have a new class for each action.

If there was any functionality in the original virtual method,
we will have to re-implement it or make an explicit call to the
original function.

Qt solves this problem by introducing signals and slots. A method can
be defined as a slot that is either private, protected, or
public. Slots are ordinary methods, but they are listed in the slot
table of the meta object. Each class utilizing the Qt object model has
an automatically-generated meta object containing type information,
inheritance information, and a list of signals, slots, and properties.

A signal is declared as if it were a usual method, but it may not be
implemented. Signals cannot be called, but emitted. Let's go back to
the event-driven GUI example. Instead of inheriting the
event-generating class, we can implement a slot which fits the signal
emitted at the interesting event.

A Code Example

Let's demonstrate this by looking at a small example. We will put two
buttons in a dialog and let them alter the text of the title bar. We
will let the functionality (i.e., the slots) be a part of our dialog,
and simply connect the "clicked" signals from the buttons to the
appropriate slots.

We begin by looking at the main function that simply initializes the
application. It is very simple, and should not pose any problems.

Notice that Qt is accompanied by a great documentation set to which
you can refer if you want to know any details. It is available online
from http://doc.trolltech.com/,
and contains reference material, examples, and in-depth tutorials. In
this tutorial, I use the free 2.3 version for win32, just to demonstrate
that the Windows version is also freely available. The code I present
here is fully compatible with any Unix or Mac version of Qt (it is, as
I mentioned, a cross-platform toolkit).

Now, we can continue by looking at the class declaration of the
example1Dialog class. This is where the Qt object model comes into
play.

First, notice that we inherit a descendant of QObject. This is
necessary; the QObject class holds much of the object model
functionality. The first line in the actual body of the class
declaration must be Q_OBJECT. This macro has two purposes: It declares
the things needed to get the object model running and works as a
marker that the meta object compiler triggers on (more about this
later).

The slots are declared in an intuitive way. Signals are declared in a
similar way, but in the "signals:" section of the declaration.

This is pretty straightforward, as slots are simply ordinary methods
that can be connected to signals. As these calls are made from inside
a descendant of a QDialog, we can set the caption as easily as shown
in the code.

We will now show the method which takes care of setting things up, the
implementation of the creator of our example1Dialog class. This method
creates a layout and buttons, and sets up the connections between the
signals and the slots.

The layout is created with a spacing of eight pixel margins between
the edges and each widget. The call to setAutoAdd means that all
widgets created with example1Dialog as a parent will be automatically
inserted into the layout.

The buttons are created with a text and the dialog as the parent. This
means that Qt will delete them from memory the moment the dialog is
deleted. Thus, we do not need to care about any complex memory
management issues. Each parent will take care of its children through
the QObject heritage.

The last thing we do is set up the connections. This is where the
magic takes place. Here, we connect each of the button's clicked
signals to the slots we created. Notice that we can send parameters
between signals and slots (almost) without any restrictions. There's
no need to declare special POD (plain old data) classes to carry
parameters; just emit the signals, and do not bother.

The Meta Object Compiler

If you try to compile the above code, you will run into problems. The
tool that is needed is the meta object compiler, the moc. It creates
code for signals and the meta object of the class. You might think
that this is an "ugly" solution. This is actually the most common
objection to using Qt. However, I have never, during three years of
usage, run into any serious problems caused by the moc or the object
model. If I encounter any problems, they are always easily solved,
thanks to good documentation and good debugging support. The biggest
benefit, however, is the syntactical clarity that the moc
provides. Anyone who knows C++ will be able to read and understand
code with signals and slots after just 1-2 minutes of introduction.

The output from the moc will be stored in the file
moc_example1dialog.cpp. Simply include this file in your makefile, and
you're ready to go!

qmake

Since version 3.0, Qt has shipped with the qmake tool. This completely
removes the makefile hell that Qt could lead to in earlier versions. A
project file (.pro) is translated into a proper makefile by qmake. For
our example, the project file would look something like this:

As you can see, the need to explicitly handle the moc_*.cpp files is
removed. Do not let the simplicity of this example fool you; qmake is
a powerful tool which can handle pretty much all the things that a
makefile can do. Through fine tuning, qmake can even handle platform
differences in, for example, third party support libraries.

Conclusions

Qt offers an extended object model which makes it easier to reuse
code. The object model introduces new syntax elements and a new
compilation stage (the moc). To remove the introduced complexity, Qt
also supplies the qmake tool, which makes it easier to build projects.

The syntax of Qt-extended code integrates nicely with C++, and makes
the code readable and easy to understand. The extensions are
transparent to the programmer, and do not introduce any new things to
think about, besides inheriting QObject or any of its descendants and
including the Q_OBJECT macro first in the class declaration.

This tutorial does not cover many of the capabilities of the Qt object
model or of Qt. It's worth mentioning that the object model introduces
supports for named properties and lots of runtime information. By
using Qt Scripting for Application (QSA), Qt objects can be scripted
in Javascript.

Recent comments

Re: Pitfalls ?
% Actually, there has been a GPL version
> of QT available since 2000. See
> the announcement. Both the embedded and
> X11 versions of QT are available under
> the GPL, and the windows port is
> available gratis for non-commercial use.

Actually, it isn't clear that the *windows* port is available for non-commercial use without exception. It seems that if you are on windows *at all* you have to pay, although there has been some discussion that you can freely use the windows port only if the application is GPL licensed.
You'll note the link you provided doesn't mention the windows port at all - and an hour or so on a search engine will find no clear answer ;)

>
> %
> % %
> % %
> % % Actually, there has been a GPL
> % version
> % % of QT available since 2000. See
> % % the announcement. Both the
> embedded
> % and
> % % X11 versions of QT are available
> % under
> % % the GPL, and the windows port is
> % % available gratis for non-commercial
> % use.
> %
> %
> % Actually that is the pitfall right
> % there. The GPL. There's nothing
> wrong
> % with it, but you need to be aware of
> it.
> % *All* programs that are linked to
> % qt/free must be GPL. Whereas GTK+,
> (or
> % the GTKMM/libsigc++ bindings) are all
> % LGPL which greatly enhances your
> freedom
> % to use the libraries while still
> % mainting the open-source nature of
> the
> % libraries themselves. It's a good
> % compromise between OSS/Freedom issues
> % and proprietary concerns.
> %
> % Michael
> %
>
>
> Since when it it a problem that non-free
> software cannot use a free library?
> Isn't it more right that those who
> charge for their products get charged by
> the developers of the libraries upon
> which their products are built? I do not
> understand this argument. Earlier, Qt
> wasn't free, now it is too free?

Aspects
There is another way for functions or messages to be shared amongst diverse classes:
Aspect Oriented Programming.
You can read more at
http://www.prakinf.tu-ilmenau.de/~czarn/aop/

You should be able to pass around a callback, or pointer to a function through an Aspect.
Anyone try comparing Aspects to Signals or Slots? Aspects seem easier, more standard, and it should be easier to create inter-(programming)language portability with Aspects.

One of the biggest shortcomings of QT compared to the GTK family, is that it is not as nice about multiple programming language support.