The Qt® 4 Resource Center

An Introduction to Qt 4 Beta 2

This document is a quick introduction to the Qt 4 beta 1. This text will form the basis of an example-driven Qt 4 tutorial in the spirit of the Independent Qt Tutorial. This does not mean the end of the current independent tutorial, since I believe that Qt 3 and 4 will be used in parallel for a long time to come.

Introduction

To start learning the Qt 4 peculiarities I decided to create a very simple dialog utilizing the new Designer, a graphically connected signal and a manually connected signal. Figure I-1 shows the resulting application.


Figure I-1

The dialog is to be designed using Designer, then the required code to get the “Add” button working and dialog shown will be written.

Designer

The first tool to use is the new Designer. It is very different from the Designer used in Qt 3. For example, it is again a design tool only. It makes no attempts at being a complete development environment. Also, the user interface has been completely redesigned and now consists of several separate windows instead of the old MDI design that was used earlier. A screenshot of Designer in action is shown in figure I-2.


Figure I-2

The user experience is also slightly different. For example, one drags and drops the widgets onto the form that is being designed. This is good and intuit, but I miss the ability to double click and then click repeatedly in the form to add many widgets of the same kind.

Figure I-3 shows the form with the widgets that are to be used, and a spacer. The widgets are: an item based list widget (the model based equivalent is referred to as a list view – good naming), two push buttons and a line edit. The maximum width of the line edit is limited to 100 pixels before a vertical followed by a horizontal layout are applied.


Figure I-3

Figure I-4 shows the form when the layouts have been applied and the text property of the line edit and push buttons have been set. Notice the rendering-miss – the line edit is not as wide as the buttons, even though they are in the final version shown in figure I-1.


Figure I-4

This is a good time to mention that I did experience the odd seg-fault while running Designer, and that the console was filled with messages shown in figure I-5. Not a big problem, but this clearly shows that this is beta software.


Figure I-5

As in earlier versions of Designer, the work is done in three modes: widget placement, tab order and connections. The working mode is selected from a dropdown combobox located at the top of the widget list dialog. This does not feel right. My opinion is that it would have been better to have a separate widgets window and a main, tool window with the current operating mode. I would probably have placed the widgets in a tool box widget instead of a list widget. This combined with the ability to connect and disconnect the different windows as in Gimp 2 would provide a better work environment.

The form with the connection from the “Clear” button to the list widget is shown in figure I-6. To create a connection, one drags from the signal source to the destination, then picks the signal and slot from a dialog (figure I-7).


Figure I-6

This works well, but a dialog with lots of connections quickly looks cluttered, even though there is a way to add extra vertexes to the lines representing connections. A better approach would have been to have a list of connections, and perhaps only show the connections for the widget under the mouse pointer as arrows.


Figure I-7

The Code

When the dialog is done, it is time to start adding code. With Qt 3, this was possible to do from within Designer, but not anymore. This is only good, in my opinion, since it clarifies the role of Designer as a user interface design tool and nothing else. Designer will be integrated with KDevelop, Visual Studio and XCode. These tools are better on project management than Qt 3's Designer ever was, so this is no loss.

The code will be based around the sub-classing approach. Here, Qt 4 really starts to show its differences from Qt 3. Instead of inheriting the created dialog, one has to sub-class both QDialog and the created dialog. Also, the dialog code is now contained in the Ui:: namespace instead of in the global namespace. The method setupUi is used to populate the QDialog with the designed user interface. Example I-1 shows the class declaration from the file formimpl.h.

#include <QDialog>

#include "ui_form.h"

class FormImpl : public QDialog, Ui::Form
{
  Q_OBJECT

public:
  FormImpl() : QDialog()
  {
    setupUi( this );

    connect( pbAdd, SIGNAL(clicked()), this, SLOT(addClicked()) );
  }

private slots:
  void addClicked();
};
Example I-1

From a Qt 3 viewpoint, the following differences can be noted:

The code creates a new class, FormImpl, that implements our form. It is based around a QDialog and the form that was designed earlier. The Q_OBJECT macro is included since we add the slot addClicked. In the constructor we first call setupUi that we inherit from Ui::Form. This method simply populates the dialog with the widgets, layouts and connections that we specified in Designer. Then the “Add” button is connected to our custom slot. The slot it-self is implemented in formimpl.cpp that is shown in example I-2.

#include "formimpl.h"

void FormImpl::addClicked()
{
  lstItems->appendItem( leValue->text() );
  leValue->setText( "" );
}
Example I-2

From a Qt 3 viewpoint, the slot implementation looks as it always has.

The code takes the text from the line edit (leValue) and appends it to the list widget (lstItems). It then clears the line edit.

The only code that is left until we have a complete application is a main function that can initialize the application. The code for this is kept in the main.cpp file that is shown in example I-3.

#include <QApplication>

#include "formimpl.h"

int main( int argc, char **argv )
{
  QApplication a( argc, argv );

  FormImpl f;
  f.exec();

  return 0;
}
Example I-3

From a Qt 3 viewpoint, this looks normal. The only difference is how the header file for the QApplication class is referred to.

The code first creates an instance of QApplication. There must always be an instance of QApplication available in GUI applications. For non-GUI applications, the QCoreApplication class is available. This is one of the adaptations of Qt to make it more lightweight and better fitted to use in non-GUI projects.

When an application instance has been created, an instance of the dialog, FormImpl, is created and then the form is executed. When executing a dialog, the dialog is shown and the exec-call is not returned until the dialog has been closed.

Conclusions

Qt 4 is the new edition of Qt. It will be used for the next generation of KDE and many other free and non-free applications. The changes that have been made are to some extent an effect of Qt 3's age. For example the new graphics engine. Some other changes are pure improvements of the design. For example, the model based items views, the ability to send signals across thread boundaries and the splitting of the library into smaller components. Most changes are for the better, even though there will be a need for more code in some situations (for example setupUi).

The tools surrounding Qt have also been updated. For example, qmake now handles the different components of Qt. Designer has been given a total overhaul, and such big changes are always not only for the best. Some features will be missed, and some developers will prefer the older working methods. Still, Designer was a heavy tool without a clearly defined task. Now it is an user interface design tool that is intended to be integrated into other development environments.

By: Johan Thelin