International * Contact  * Sitemap  * Links  * Register Software
Search  
 SUSE - simply change

Home Users

 Novell
  | Home  |  | Overview  |  | Products  |  | Support  |  | Downloads  |  | Distributors & Resellers  |
  SUSE LINUX Support   Online Help   License information   Security   Feedback
  Printable page

Qt - Portable GUI Programming under Linux/Unix/Windows

Helmut Herold

This is a brief overview of the C++ class library Qt, which enables simple and portable GUI programming. This library was developed by the Norwegian company Trolltech. Programs developed with Qt can run immediately under all flavors of Linux/Unix as well as all Windows systems without any additional porting work. The only thing you need to do is to compile and link the programs with the appropriate compilers (Visual C++ or Borland C++ under Windows systems or the cc compiler provided by the respective Linux/Unix system).

In the future, the portability of newly developed software will likely emerge as an increasingly important issue. After all, why should anyone develop a program that runs only on Windows systems and voluntarily exclude the market comprised of millions of Unix and Linux system users? The reverse case, of course, applies as well. Naturally, this begs the question why newly developed programs aren't written in Java programming language to begin with, since Java also provides programmers with the option to create portable programs. While Java's portability, just like Qt's, is surely an advantage, the speed at which Java programs run cannot keep up with that of Qt programs. One should also note that Qt is a C++ library. Consequently, this library can be used by programmers who have mastered C programming language but have only a basic knowledge of C++. There is a very large group of software developers who fit this profile.

Table of Contents

 

Introduction

Qt's Advantages

These are the benefits of using Qt for the development of new software:

Qt is free for Windows and Unix systems (such as Linux, FreeBSD or Solaris)

if you are writing free software for these systems (also see The QPL, an Open Source License).

Qt is portable and hassle-free.

Programs written with Qt run under Linux/Unix as well as under Windows. That is not the case with MFC, for example, because programs developed with MFC run under Windows only. Moreover, many programmers who have worked with both MFC and Qt say that Qt is easier to work with.

Qt is fast.

Programs written with Qt run very quickly.

 

The Term `Widget´

Qt works with so-called widgets. Under Linux/Unix, the term is used to refer to windows: Widget is a lexical contraction based on the two terms Windows and Gadget (this corresponds to Controls under Windows operating systems). Almost everything displayed on an interface developed in Qt is a widget: buttons, scroll bars, dialog boxes, etc. Widgets can, in turn, contain their own subwidgets, such as, for example, buttons or text input fields in a dialog box. In Qt, a widget is an object that belongs to a class derived from the class QWidget. Qt contains many predefined widgets, even though a Qt programmer can also define his own widgets.

 

Qt Online Documentation in HTML Format

Qt has excellent online documentation in HTML format. The documentation is included with every Qt distribution. To read the online documentation, you must use a Web browser such as Netscape Navigator or Internet Explorer. You can also use other browsers such as arena or lynx under Linux, since the Qt online documentation does not require special HTML constructs nor Java or JavaScript. In your browser window, first open the index.html file in the respective Qt installation's doc directory (under Linux/Unix systems, /usr/lib/qt/doc/html or /usr/lib/qt2/doc/html) or, alternatively, Trolltech's homepage (online documentation at Trolltech) opens the Qt documentation's main page (see Figure 1).

Online Qt documentation

Figure 1: Qt reference documentation main page

For an overview of how the Qt class tree is organized you should first click on Annotated Class List to see a list of all public Qt classes, along with a one-line brief description. Later on, once you are more familiar with using Qt you can usually go directly from the main page to Alphabetical Class List. This function displays a list without brief descriptions and lists more classes per page. For a first impression of individual class descriptions, you can, for example, click on the QButton link. QButton is the class used for creating buttons and for handling the buttons' interactions with the program (see Figure 2).

The QButton class

Figure 2: QButton reference documentation

The first line in Figure 2 contains a short description of the respective class. The second line specifies the name of the header file in which this class has been defined, followed by the name of the basic class from which this class was derived. The next line contains a list of classes that were, in turn, derived from this class (QButton in this case). In Figure 2, these classes are QCheckBox, QPushButton, QRadioButton and QToolButton. The link List of all member functions is important if you want to get an overview of all member functions, that is, not just those member functions defined within the class itself, but also those member functions that inherited their class designations form their parent classes. The system then displays a list of all Public Members defined within this class directly, as well as possible lists from Public Slots, Signals or Protected Members, which are offered by this class. Following these lists you can see detailed descriptions of the respective classes. These descriptions often include examples illustrating the use of these classes.

 

Fundamental Qt Concepts and Constructs

This section briefly introduces Qt's fundamental concepts and constructs. First, we will introduce a simple example program that illustrates the basic structure of a Qt program. This program opens a small window with text (Label) in the middle and a button above and below the text. Clicking either of these two buttons quits the program. However, to use the upper button, you only need to move the mouse onto the button and then press the left mouse button, whereas you can activate the lower button only with a full click (pressing and releasing) of the left mouse button. Next, we will first introduce a second Qt program to illustrate Qt's important Signal-Slot Concept before presenting a second example program that helps explain how you can define your own slots in Qt.

Please refer to the end of this chapter, where you can find Chapter 3 excerpted from the Qt book published by SuSE PRESS. This chapter is available in PDF or PS file format. It includes another copy of this brief description and also introduces the class QString , which is an abstraction towards Unicode text and the string concept in classic C (char-array with 0 byte as end of string). The chapter also introduces the color modes used by Qt, defines color groups and explains how you can edit color palettes for widgets. The final section of this chapter describes how to use the class QPainter to create a small paint program on the screen that lets you draw with your mouse. You will learn how to gradually extend the program by adding menus and scroll bars. The program's final version even lets you save and reload the pictures you created.

 

An Initial Qt Program with Text and Buttons

Here we create the very first Qt program in order to illustrate the fundamental concepts that apply to almost all Qt programs. This initial program twobuttons.cpp creates a small window with some text (Label) in the middle and one button above and below the text (see Figure 3). Clicking either one of the buttons quits the program. However, the two buttons differ in how they work: to activate the upper button you merely need to press the left mouse button, whereas the lower button can be activated only with a full click (pressing and releasing) of the left mouse button Either way, the system exits the program and closes the window.

twobuttons.cpp program window

Figure 3: twobuttons.cpp program window

The system uses highlights to mark those lines in the following program twobuttons.cpp that are discussed in more detail below.


  1  #include <qapplication.h>   //... required in every Qt program
  2  #include <qlabel.h>         //... for class QLabel
  3  #include <qpushbutton.h>    //... for class QPushbutton
  4  #include <qfont.h>          //... for class QFont
  5
  6  int main( int argc, char* argv[] )
  7  {
  8        // Instantiation of a QApplication object; always required
  9     QApplication myapp( argc, argv );
 10
 11        // Main widget where buttons and text are located.
 12     QWidget* mywidget = new QWidget();
 13           //... horizontal, vertical position, width, height in pixels
 14     mywidget->setGeometry( 200, 100, 450, 150 );
 15
 16        // Instantiation of the first button
 17     QPushButton* first_button = new QPushButton(
                  "Quit (pressed(): upon mouse click)", mywidget );
 18           // Rel. position (30,10) in mywidget (400 wide, 30 high)

 19     first_button->setGeometry( 30, 10, 400, 30 );
 20           //... If signal 'pressed' occurs with first_button,
 21           //... activate SLOTcode 'quit' (exit program)
 22     QObject::connect( first_button, SIGNAL( pressed() ), &myapp, SLOT( quit()));
 23
 24        // Instantiating a label (text only)
 25     QLabel* mylabel = new QLabel( "A program with two Quit buttons",mywidget);
 26           // Rel. position (30,40) in mywidget (400 wide, 50 high)
 27     mylabel->setGeometry( 30, 40, 400, 50 );
 28     mylabel->setFont(QFont("Times", 18, QFont::Bold) );
 29
 30        // Instantiating a second button
 31     QPushButton* second_button = new QPushButton(
                  "Quit (clicked(): only after clicking and release of the mouse button)", mywidget );
 32           // Rel. position (30,90) in mywidget (400 wide, 50 high)
 33     second_button->setGeometry( 30, 90, 400, 50 );
 34           // If signal 'clicked' occurs with second_button,
 35           // activate SLOTcode 'quit' (exit program)
 36     QObject::connect( second_button, SIGNAL( clicked() ), &myapp, SLOT( quit()));
 37
 38     myapp.setMainWidget( mywidget ); // 'mywidget' is the main widget
 39     mywidget->show();    // Show main widget with its subwidgets
 40     return myapp.exec(); // Transfer of control to 'exec' method
 41                          // from QApplication
 42  }

Program twobuttons.cpp: First Qt program with window containing two buttons and text

The first four lines of the program twobuttons.cpp include Qt header files. In most cases, the header files have the same names (without .h) as the corresponding class names declared in those files. There are a few exceptional cases with multiple classes in one header file, such as, for example the two class declarations QlistView and QlistViewItem in <qlistview.h>. The following section contains more detailed descriptions of the most important commands in the program twobuttons.cpp.

  9     QApplication myapp( argc, argv );

This object is responsible for all event handling tasks and is required in all Qt programs. It is necessary to pass the command line arguments to the QApplication object's constructor, since QApplication recognizes several special command line options. If such options are specified, QApplication can analyze them independently and then remove them from argv, incrementally decreasing argc accordingly. For example, -style is one such special option. With this option, those who call a Qt application under Linux/Unix as well as under Windows systems can define a special widget style as the default style for the application. If the application program has its own command line arguments, the program should never analyze these arguments until after the QApplication object has been instantiated.

 12     QWidget* mywidget = new QWidget();

This command creates the main widget mywidget, which serves as the container for the subwidgets to be created later on (text and two buttons). In this context you should note that widgets (main widget, buttons, sliders, etc.) should always be created on the heap, since the system deletes them automatically if their parent widgets are deleted. Qt beginners often make the mistake of instantiating a widget directly in the stack, that is, without using new. This causes serious errors during subsequent program processes and such errors are very difficult to locate.

 14    mywidget->setGeometry( 200, 100, 450, 150 );

This command calls the setGeometry() method. Since this method is defined within the QWidget class (main widget) and is inherited by all subwidgets, this method is also available to all subsequently created subwidgets (labels and two buttons) (see line 19, 27 and 33 in the previous listing). The third parameter defines (in pixels) the width of the respective widget and the fourth parameter defines its height. The specifications of the horizontal and vertical positions (first two arguments) are always relative to the parent widget. Since mywidget is the main widget and thus does not have a parent widget, the coordinates specified in line 14 refer to the entire screen. However, the following commands:

 19     first_button->setGeometry( 30, 10, 400, 30 );
 27     mylabel->setGeometry( 30, 40, 400, 50 );
 33     second_button->setGeometry( 30, 90, 400, 50 );

specify coordinates relative to the main widget's (object mywidget) upper left corner.

 17     QPushButton* first_button = new QPushButton(
                  "Quit (pressed(): upon mouse click)", mywidget );

This command creates the first button. The constructor's first parameter QPushButton defines the text that appears on the button, while the second parameter specifies in which parent widget this button appears (mywidget in this example). Before we move on to the next command, you should note that if you left-click the mouse on one of these buttons, the button automatically sends the signal pressed().

 22     QObject::connect( first_button, SIGNAL(pressed()), &myapp, SLOT(quit()));

This command works as follows: when the button first_button sends the predefined signal pressed(), the system sends the signal to the slot specified here. You can use this slot to define the action the system should execute when the corresponding signal is sent. In reaction to receiving the pressed() signal (from first_button), the connect() method (from the QObject class) sets up the Qapplication's predefined slot routine quit(), which terminates the program immediately. The signal-slot concept is probably the most important programming concept you need to know about when working with Qt. In contrast to other GUI toolkits, Qt strictly separates the signals that a widget can send from the actions (slots) whose code is executed whenever a signal is received. The widget sending a signal does not know where the signal is routed, since this connection does not exist until the programmer uses the connect() method to create it. In most programs, the majority of predefined signals are not connected to any slot, so that no action is initiated when these signals are received. On the other hand, when you create a slot you do not yet need to know which signals will be connected to this slot. Additional information about signals and slots is provided below.

 25     QLabel* mylabel = new QLabel( "A program with two Quit buttons",mywidget);
 27     mylabel->setGeometry( 30, 40, 400, 50 );
 28     mylabel->setFont(QFont("Times", 18, QFont::Bold) );

The command in line 25 is used to create a label. The constructor's first parameter QLabel defines the text that appears on this label, while the second parameter specifies in which parent widget this label appears (mywidget in this example). Next, the setGeometry() method inherited from the QWidget class (main widget) is used to define the label's relative position within the main widget (mywidget object). Next the setFont() method (another method inherited from the main widget), along with the QFont class, are used to specify the text output font.

 31     QPushButton* second_button = new QPushButton(
                "Quit (clicked(): only after clicking and release of the mouse button)", mywidget );
 33     second_button->setGeometry( 30, 90, 400, 50 );
 36     QObject::connect( second_button, SIGNAL(clicked()), &myapp, SLOT(quit()));

The command in line 31 is used to create a second button. The constructor's first parameter QPushButton once again defines the text that appears on the button, while the second parameter specifies in which parent widget this button appears (mywidget in this example). Next, the setGeometry() method inherited from the QWidget class is used to define this button's relative position in the main widget (mywidget object). The command in line 36 defines the following: When the second_button button sends the predefined signal clicked(), the system executes the Qapplication's predefined slot routine quit(), which ends the program immediately. In contrast to the previously discussed pressed() signal, the clicked() signal is triggered only after the user presses as well as releases the left mouse button over this button.

 38     myapp.setMainWidget( mywidget ); // 'mywidget' is the main widget

This command instructs the QApplication object that mywidget takes on the main widget's role. The notable feature of a main widget is that the system quits the respective program completely if the user closes the main widget.

 39     mywidget->show();    // Show main widget with its subwidgets

This command instructs the system to display the main widget along with all its subwidgets on the screen. Note that you have the option to show or hide (from view) every widget. By default, the system hides all widgets that are not subwidgets of a visible widget.

 40     return myapp.exec();

This final command turns over full control of the program processes to the myapp object (QApplication class) created at the beginning.

We can now stipulate that our future Qt programs will all have the following basic structure:

 

 #include <q...h>
    ....

 int main( int argc, char* argv[] )
 {
    QApplication myapp( argc, argv );
    QWidget* mywidget = new QWidget();
    mywidget->setGeometry( x_pos, y_pos, width, height );
    .......
    .......
    myapp.setMainWidget( mywidget );
    mywidget->show();
    return myapp.exec();
 }

 

More about the Qt Signal-Slot Concept

At this point, we are first going to create a second program to illustrate Qt's important signal-slot concept. Then we will introduce a second example program in order to explain how you can define your own Qt slots.

 

Example Program: Slider and Buttons to Increase/Decrease LCD Numbers

This program named slider.cpp creates a small window with a 7-segment LCD number displayed in the middle of the window. You can increase or decrease this number by using the slider displayed above the number or by using the two buttons shown below the number (see Figure 4 for Motif style and Figure 5 for Windows style).

Motiv style slider

Figure 4: Using the slider or buttons to incrementally increase or decrease an LCD number (Motif style)

Windows style slider

Figure 5: Using the slider or buttons to incrementally increase or decrease an LCD number (Windows style)

The following section explains the new commands needed to understand the program slider.cpp.

 14     QSlider* myslider = new QSlider( 0,  // minimum possible value
 15                                     99,  // maximum possible value
 16                                      1,  // Increment
 17                                     20,  // Start value
 18                                     QSlider::Horizontal,  // Direction
 19                                      mywidget ); // Parent widget

This command creates a QSlider widget (slider). In the process, the system uses the associated constructor's arguments to configure the slider accordingly.

 23    QLCDNumber* mylcdnum = new QLCDNumber( 2,          // number of digits
 24                                           mywidget ); // Parent widget

This command creates a QLCDNumber widget (LCD number display). The associated constructor's first argument defines how many sequential LCD digits this widget can display.

 26    mylcdnum->display( 20 ); // Display start value

This command instructs the system to use the number 20 as the start value when the mylcdnum widget is first displayed. display() is not actually a QLCDNumber class method. Instead, it is a method from the class of available slots. However, as this command illustrates, slots can be used just like methods, while the converse is not possible. Unlike slots, you cannot use a connect() call to connect methods with a signal.

The following program slider.cpp highlights the newly introduced constructs in the display.


  1  #include <qapplication.h>
  2  #include <qpushbutton.h>
  3  #include <qslider.h>    // for class QSlider
  4  #include <qlcdnumber.h> // for class QLCDNumber
  5
  6  int main( int argc, char* argv[] )
  7  {
  8     QApplication myapp( argc, argv );
  9
 10     QWidget* mywidget = new QWidget();
 11     mywidget->setGeometry( 400, 300, 200, 150 );
 12
 13     //.... Creating a slider
 14     QSlider* myslider = new QSlider( 0,  // minimum possible value
 15                                     99,  // maximum possible value
 16                                      1,  // Increment
 17                                     20,  // Start value
 18                                     QSlider::Horizontal,  // Direction
 19                                      mywidget );      // Parent widget
 20     myslider->setGeometry( 10, 10, 180, 30 );
 21
 22     //.... Creating an object to display LCD numbers
 23    QLCDNumber* mylcdnum = new QLCDNumber( 2,          // number of digits
 24                                            mywidget ); // Parent widget
 25     mylcdnum->setGeometry( 60, 50, 80, 50 );
 26     mylcdnum->display( 20 ); // Display start value
 27
 28    // Connect slider and numeric display
 29     QObject::connect( myslider, SIGNAL( valueChanged( int ) ),
 30                       mylcdnum, SLOT( display( int ) ) );
 31
 32     // Two buttons to gradually increase and
 33     // decrease the slider values
 34     QPushButton* decrement = new QPushButton( "<", mywidget );
 35      decrement->setGeometry( 10, 110, 50, 30 );
 36      decrement->setFont(QFont("Times", 18, QFont::Bold) );
 37      decrement->setPalette( QPalette( QColor(255, 0, 0), Qt::white ) );
 38
 39     QPushButton* increment = new QPushButton( ">", mywidget );
 40      increment->setGeometry( 140, 110, 50, 30 );
 41      increment->setFont(QFont("Times", 18, QFont::Bold) );
 42      increment->setPalette( QPalette( QColor(0, 255, 0), Qt::white ) );
 43
 44     // Connect the buttons' clicked() signal to the slots that
 45     // increase or decrease the slider value
 46     QObject::connect( decrement, SIGNAL( clicked() ),
 47                       myslider, SLOT( subtractStep() ) );
 48     QObject::connect( increment, SIGNAL( clicked() ),
 49                       myslider, SLOT( addStep() ) );
 50
 51     myapp.setMainWidget( mywidget );
 52     mywidget->show();
 53     return myapp.exec();
 54  }

Program slider.cpp: LCD number you can edit with the slider or the buttons

Explanation:

 29     QObject::connect( myslider, SIGNAL( valueChanged( int ) ),
 30                       mylcdnum, SLOT( display( int ) ) );

This command instructs the system to activate the slot routine display(int) with the current slider value whenever the slider value is edited. Whenever you edit the slider value, the myslider widget sends the signal valueChanged(int) with the current slider value as an argument, and this argument is passed to display(int) as an argument.

 37      decrement->setPalette( QPalette( QColor(255, 0, 0), Qt::white ) );

 42      increment->setPalette( QPalette( QColor(0, 255, 0), Qt::white ) );

These two arguments define the decrement button's background color as red and the increment button's background color as green.

 46     QObject::connect( decrement, SIGNAL( clicked() ),
 47                       myslider, SLOT( subtractStep() ) );
 48     QObject::connect( increment, SIGNAL( clicked() ),
 49                       myslider, SLOT( addStep() ) );

This section of code specifies that one of the two buttons decrement or increment must execute the myslider widget's slot routine subtractStep() or addStep() whenever the system sends the signal clicked().

 

Example Program: Slider and buttons to edit font size with text display

Here you learn how to define your own slots and related issues you must be aware of when generating the program. The current program textsize.cpp is an extension of the previous program slider.cpp. The extended program always interprets the displayed LCD number as a font size and always displays an example of the text in this font size at the right (see Figure 6).

textsize.cpp

Figure 6: Slider and buttons to edit font size with text display

The goal is to define for the textsize.cpp program your own slot that is activated whenever the slider value changes. This slot is responsible for displaying the text with the new font size that matches the slider value. Qt has introduced several new keywords for the signal-slot concept. The preliminary processor translates these keywords into the appropriate C++ syntax. You must use the following Qt syntax to define classes that declare their own slots and/or signals.

 Class MyClass : public QObject
 {
    Q_OBJECT
     ....
 signals:
     //.... This is where the corresponding signals are declared, for example:
       void  letter_a_pressed ();
 ....
 public slots:
     //.... This is where the public slots are declared, for example:
       void  let_text_flash();

 private slots:
     //.... This is where the private slots are declared, for example:
       void  an_internal_slot();

     //.... Other declarations are also possible here
 }

Note the following items when declaring slots and signals:

  1. The declaration of slots and signals is permitted only within C++ classes.
    This means that you cannot declare a function intended to serve as a slot routine or declare a signal outside of a class. Doing this would violate the C++ philosophy anyway.
  2. Every class declaring its own slots and/or signals must be derived directly or indirectly from the QObject class.
    Since QWidget itself is derived from QObject this is not a serious limitation. Besides, in most cases, programming with Qt involves classes derived directly or indirectly from QWidget anyway.
  3. Every class definition that declares its own slots and/or signals must contain the macro Q_OBJECT.
    Keep in mind that you must not place a semicolon behind this macro.

Here you can find a summary of rules applicable to the declaration of slots and signals.

Given this knowledge, we can now define a class named Font derived from the QLabel class that provides its own slot refresh(int) to refresh the text (with the slider value as the font size). We will create a header file named textsize.h for this purpose:

 class Font: public QLabel
 {
    Q_OBJECT   // required, since Font contain slots

 public:
    Font( char const* text, QWidget *parent ) : QLabel( text, parent )  {

 public slots:
    void refresh( int size) {
       setFont(QFont("Times", size) );
       repaint();
    }
 };

Program textsize.h: Header file containing the definition of its own `font´ class with its own slot.

The system uses the value provided by the `size´ parameter to reset the font size for text output in the slot refresh(int size). The method repaint() then ensures that the text in this label is actually displayed in the new font.

We can now use this new class definition to create our new program textsize.cpp. The new constructs that were added compared to the previous program slider.cpp are highlighted.


  1  #include <qapplication.h>
  2  #include <qpushbutton.h>
  3  #include <qslider.h>
  4  #include <qlcdnumber.h>
  5  #include <qlabel.h>
  6  #include "text_size.h" // contains new class 'font'
                            // with its own slot 'refresh'
  7
  8  int main( int argc, char* argv[] )
  9  {
 10     QApplication myapp( argc, argv );
 11
 12     QWidget* mywidget = new QWidget();
 13     mywidget->setGeometry( 400, 300, 460, 150 );
 14
 15     //.... Creating a slider
 16     QSlider* myslider = new QSlider( 0,  // minimum possible value
 17                                      99, // maximum possible value
 18                                       1, // Increment
 19                                      20, // Start value
 20                                      QSlider::Horizontal,  // Direction
 21                             mywidget );       // Parent widget
 22     myslider->setGeometry( 10, 10, 180, 30 );
 23
 24     //.... Creating a widget to display LCD numbers
 25     QLCDNumber* mylcdnum = new QLCDNumber( 2,          // number of digits
 26                                            mywidget ); // Parent widget
 27     mylcdnum->setGeometry( 60, 50, 80, 50 );
 28     mylcdnum->display( 20 ); // Display start value
 29
 30     // Connect slider and numeric display
 31     QObject::connect( myslider, SIGNAL( valueChanged( int ) ),
 32                       mylcdnum, SLOT( display( int ) ) );
 33
 34     // Two buttons to gradually increase and
 35     // decrease the slider values
 36     QPushButton* decrement = new QPushButton( "<", mywidget );
 37      decrement->setGeometry( 10, 110, 50, 30 );
 38      decrement->setFont(QFont("Times", 18, QFont::Bold) );
 39      decrement->setPalette( QPalette( QColor(255, 0, 0), Qt::white ) );
 40
 41     QPushButton* increment = new QPushButton( ">", mywidget );
 42      increment->setGeometry( 140, 110, 50, 30 );
 43      increment->setFont(QFont("Times", 18, QFont::Bold) );
 44      increment->setPalette( QPalette( QColor(0, 255, 0), Qt::white ) );
 45
 46     // Connect the buttons' clicked() signal to the slots that
 47     // increase or decrease the slider value
 48     QObject::connect( decrement, SIGNAL( clicked() ),
 49                       myslider, SLOT( subtractStep() ) );
 50     QObject::connect( increment, SIGNAL( clicked() ),
 51                       myslider, SLOT( addStep() ) );
 52
 53     // Label to display font (size)
 54     Font* display = new font( " Text", mywidget );
 55     display>setGeometry( 200, 10, 250, 130 );
 56     display>setFont(QFont("Times", 20) );
 57     display>setPalette( QPalette( Qt::white, Qt::white ) );
 58
 59     // Connect slider and label (for text display)
 60     QObject::connect( myslider, SIGNAL( valueChanged( int ) ),
 61                       display, SLOT( refresh( int ) ) );
 62
 63     myapp.setMainWidget( mywidget );
 64     mywidget->show();
 65     return myapp.exec();
 66  }

Program textsize.cpp: Slider and buttons to edit font size with text display

The following section explains the new commands needed to understand the program textsize.cpp.

First, line 54 creates an object named Display of the Font class. This is a label widget, since the Font class is derived from the QLabel class. This label displays the text `Text´. Line 55 defines the Display widget's position and size, while line 56 specifies the font to use for text output. Line 57 specifies the color `white´ (Qt::white) as the background color for the label widget.

Lines 60 and 61 specify that whenever the slider value is changed - as indicated by sending the valueChanged(int) signal - the system executes the slot routine refresh (int) defined by Display, so that the text is refreshed and displayed in the new font size, which matches the slider value. Whenever you define classes that define their own slots and/or signals, you must first compile them with the Meta-Object-Compiler (moc) included in the Qt distribution. If you are using the tool tmake provided by Trolltech to create the makefile, the tool automatically knows that it must generate a corresponding moc call in the makefile.

For instance, the following example uses the file textsize.pro for our program:

  TEMPLATE = app
  CONFIG = qt warn_on release
  SOURCES = textsize.cpp
  HEADERS = textsize.h
  TARGET = textsize

We then call

tmake textsize.pro -o Makefile

This call then generates a makefile, which means that the only task left to do is to call make or nmake.

 

Rules for Declaring Your Own Slots and Signals

Below is another summary of rules that apply to the signal-slot concept:

  1. The declaration of slots and signals is permitted only within C++ classes.
    This means that you cannot declare a function intended to serve as a slot routine or declare a signal outside of a class. Doing this would violate the C++ philosophy anyway.
  2. Every class declaring its own slots and/or signals must be derived directly or indirectly from the QObject class.
    Since QWidget itself is derived from QObject this is not a serious limitation. Besides, in most cases, programming with Qt involves classes derived directly or indirectly from QWidget anyway.
  3. Every class definition that declares its own slots and/or signals must contain the macro Q_OBJECT.
    Keep in mind that you must not place a semicolon behind this macro.
  4. You can declare and implement slots just like any other C++ method.
    Slots are actually methods that you can also call directly outside of a connect() call. By contrast, you cannot specify methods as arguments of a connect() call.
  5. The only thing you must do prior to defining slots is to assign the keyword slots to the appropriate keyword protection type public or private.
    Of course, you can also define protected slots and define them virtually. The only difference between slots compared to methods is that it is not permitted to declare slots as static.
  6. Slots can have parameters just like methods.
    Make sure that the signal specified for a connect() call has the same parameter types as the corresponding slot. However, it is also possible for a slot to have fewer parameters than the signal the slot is connected to if the slot does not need all of the parameters provided by the signal.
  7. The syntax for slot names is the same as the syntax for methods.
    However, some programmers embed the character string slot in the slot name to be able to identify them as slots immediately. Note that Qt does not follow this convention for naming its predefined slots.
  8. To define signals in a class, you must first specify the keyword 'signals'.
    Other than that, declaring signals corresponds to declaring other member functions, with one exception: signals can only be declared; they must never be implemented directly.
  9. The Qt keyword 'emit' is available for sending a signal in a component.
    If, for example, you declared the signal void color_changed (int) in the class definition, you can make the following call: emit color_changed(173);
  10. Use the QObject::connect() method to connect signals and slots.
    There are overburdened variants of this method available. However, here we are only using the static variant with four parameters:
    QObject::connect( signal_object,            // Object sending the signal
                      SIGNAL(signal_name(...)), // Signal to connect to slot
                      slot_object,              // Object receiving the signal
                      SLOT(slot_name(...)) );   // Slot to connect to signal
    
    You can connect as many slots as you want to a signal as well as connect any number of signals to a slot. Since Qt has not yet defined the slot call sequence, there is no guarantee that the system will call slots in the same order they were connected to signals with the connect() method.

 

This Summary Version and More (in German), PDF and PS

SuSE PRESS has published a Qt book. Chapter 3 of this book not only contains a copy of this overview, but also introduces the QString class, which is an abstraction towards Unicode text and the string concept in classic C (char-array with 0 byte as end of string).

The chapter also introduces the color modes used by Qt, defines color groups and explains how you can edit color palettes for widgets.

The final section of this chapter describes how to use the class QPainter to create a small paint program on the screen that lets you draw with your mouse. You will learn how to gradually extend the program by adding menus and scroll bars The program's final version even lets you save and reload the pictures you created.

More about Qt (Recommended Reading)

More information about Qt is available in this Qt book published by SuSE PRESS:

 


The Qt Book

The Qt Book - Portable GUI Programming under Linux/Unix/Windows

by Helmut Herold
 
in German, first edition 2001
hardcover, with CD-ROM, 1,184 pages,
DM 129 / EUR 66
ISBN 3-934678-76-9

 

Table of contents and excerpt from this Qt book


 

Due to overlong lines of code contained in this document we recommend to use the "Landscape" printing option of your browser.

Further Information

* Reseller
* Reviews
* Support Database
* Hardware Database
* Education Program

Quick Links

* Security
* Support Portal
* Mailing Lists
* Feedback
* SUSE LINUX eNewsletter

Subscribe now!

Get the Live DVD and Run Linux in Seconds!

SUSE LINUX 9.1 Personal Live CD

Want a hassle-free way to try Linux? Download SUSE LINUX Professional 9.2 Live DVD. It runs completely from your DVD drive. No need to install anything.

 This server is powered by NPS.
Linux is a registered trademark of Linus Torvalds.
Last changed: 19.02.2004 12:46 MET by webmaster@suse.de