<<

• Hello Qt • Making Connections • Using the Reference 11 Documentation Getting Started

This chapter shows how to combine basic C++ with the functionality provided by Qt to create a few small (GUI) applications. This chapter also introduces two key Qt ideas: “signals and slots” and layouts. In Chapter 2, we will go into more depth, and in Chapter 3, we will start building a realistic application.

Hello Qt

Here’s a very simple Qt program:

001 #include 002 #include

003 int main(int argc, char *argv[]) 004 { 005 QApplication app(argc, argv); 006 QLabel * = new QLabel("Hello Qt!", 0); 007 app.setMainWidget(label); 008 label->show(); 009 return app.exec(); 010 } We will first study it line by line, then we will see how to compile and run it. Lines 1 and 2 include the definitions of the QApplication and QLabel classes. Line 5 creates a QApplication object to manage application-wide resources. The QApplication constructor requires argc and argv because Qt supports a few command-line arguments of its own. Line 6 creates a QLabel widget that displays “Hello Qt!”. In Qt terminology, a widget is a visual element in a user interface. Buttons, menus, scroll bars, and frames are all examples of widgets. Widgets can contain other widgets; for

3 4 1. Getting Started example, an application is usually a widget that contains a QMenuBar,a QToolBar,aQStatusBar, and some other widgets. The 0 argument to the QLabel constructor (a null pointer) means that the widget is a window in its own right, not a widget inside another window. Line 7 makes the label the application’smain widget. When the user closes the main widget (by clicking X in the window’s title bar, for example), the program terminates. Without a main widget, the program would keep running in the background even after the user has closed the window. Line 8 makes the label visible. Widgets are always created hidden, so that we can customize them before showing them, thereby avoiding flicker. Line 9 passes control of the application on to Qt. At this point, the program enters a kind of stand-by mode, where it waits for user actions such as mouse clicks and key presses. User actions generate events (also called “messages”) to which the program can respond, usually by executing one or more functions. In this respect, GUI applications differ drastically from conventional batch programs, which typi- cally process input, produce results, and terminate without human interven- tion.

Figure 1.1. Hello on Windows XP

It is now time to test the program on your machine. First, you will need to in- stall Qt 3.2 (or a later Qt 3 release), a process that is explained in Appendix A. From now on, we will assume that you have a correctly installed copy of Qt 3.2 and that Qt’s bin directory is in your PATH environment variable. (On Windows, this is done automatically by the Qt installation program, so you don’t need to worry about it.) You will also need the Hello program’s source code in a file called hello.cpp in a directory called hello.You can type in hello.cpp yourself, or copy it from the CD provided with this book, where it is available as \examples\chap01\hello\ hello.cpp. From a command prompt, change directory to hello, then type qmake -project to create a platform-independent project file (hello.pro), then type qmake hello.pro to create a platform-specific makefile from the project file. Run make to build the program, and run the program by typing hello on Windows, ./hello on Unix, and open hello.app on Mac OS X. If you are using Microsoft Visual C++, Hello Qt 5 you will need to run nmake instead of make. Alternatively, you can create a Visual Studio project file from hello.pro by typing qmake -tp vc hello.pro and then build the program in Visual Studio.

Figure 1.2. A label with basic HTML formatting

Now let’s have some fun: We will brighten up the label by using some simple HTML-style formatting. This can be done by replacing the line QLabel *label = new QLabel("Hello Qt!", 0); with QLabel *label = new QLabel("

Hello " "Qt!

", 0); and rebuilding the application.

Making Connections

The next example illustrates how to respond to user actions. The application consists of a that the user can click to quit. The source code is very similar to Hello, except that we are using a QPushButton instead of a QLabel as our main widget, and we are connecting a user action (clicking a button) to a piece of code. This application’s source code is on the CD in the file \examples\chap01\quit\ quit.cpp.

Figure 1.3. The Quit application

001 #include 002 #include

003 int main(int argc, char *argv[]) 004 { 005 QApplication app(argc, argv); 006 QPushButton *button = new QPushButton("Quit", 0); 6 1. Getting Started

007 QObject::connect(button, SIGNAL(clicked()), 008 &app, SLOT(quit())); 009 app.setMainWidget(button); 010 button->show(); 011 return app.exec(); 012 } Qt’s widgets emit signals to indicate that a user action or a change of state has occurred.# For instance, QPushButton emits a clicked() signal when the user clicks the button. A signal can be connected to a function (called a slot in that context), so that when the signal is emitted, the slot is automatically executed. In our example, we connect the button’s clicked() signal to the QApplication object’s quit() slot. The SIGNAL() and SLOT() macros are part of the syntax; they are explained in more detail in the next chapter. We will now build the application. We assume that you have created a direc- tory called quit containing quit.cpp. Run qmake in the quit directory to gener- ate the project file, then run it again to generate a makefile: qmake -project qmake quit.pro

Now build the application, and run it. If you click Quit,orpress Space (which presses the button), the application will terminate. The next example demonstrates how to use signals and slots to synchronize two widgets. The application asks for the user’s age, which the user can enter by manipulating either a spin box or a slider.

Figure 1.4. The Age application

The application consists of three widgets: a QSpinBox,aQSlider, and a QHBox (horizontal layout box). The QHBox is the application’s main widget. The QSpinBox and the QSlider are rendered inside the QHBox; they are children of the QHBox.

Caption 

QHBox QSpinBox QSlider

Figure 1.5. The Age application’s widgets

#Qt signals are unrelated to Unix signals. In this book, we are only concerned with Qt signals. Making Connections 7

001 #include 002 #include 003 #include 004 #include

005 int main(int argc, char *argv[]) 006 { 007 QApplication app(argc, argv);

008 QHBox *hbox = new QHBox(0); 009 hbox->setCaption("Enter Your Age"); 010 hbox->setMargin(6); 011 hbox->setSpacing(6);

012 QSpinBox *spinBox = new QSpinBox(hbox); 013 QSlider *slider = new QSlider(Qt::Horizontal, hbox); 014 spinBox->setRange(0, 130); 015 slider->setRange(0, 130);

016 QObject::connect(spinBox, SIGNAL(valueChanged(int)), 017 slider, SLOT(setValue(int))); 018 QObject::connect(slider, SIGNAL(valueChanged(int)), 019 spinBox, SLOT(setValue(int))); 020 spinBox->setValue(35);

021 app.setMainWidget(hbox); 022 hbox->show();

023 return app.exec(); 024 } Lines 8 to 11 set up the QHBox.# We call setCaption() to set the text displayed in the window’s title bar. Then we put some space (6 pixels) around and in between the child widgets. Lines 12 and 13 create a QSpinBox and a QSlider with the QHBox as the parent. Even though we didn’t set the position or size of any widget explicitly, the QSpinBox and QSlider appear nicely laid out side by side inside the QHBox. This is because QHBox automatically assigns reasonable positions and sizes to its children based on their needs. Qt provides many classes like QHBox to free us from the chore of hard-coding screen positions in our applications. Lines 14 and 15 set the valid range for the spin box and the slider. (We can safely assume that the user is at most 130 years old.) The two connect() calls shown in lines 16 to 19 ensure that the spin box and the slider are synchro- nized so that they always show the same value. Whenever the value of one widget changes, its valueChanged(int) signal is emitted, and the setValue(int) slot of the other widget is called with the new value. Line 20 sets the spin box value to 35. When this happens, the QSpinBox emits the valueChanged(int) signal with an int argument of 35. This argument is

#If you get a compiler error on the QHBox constructor, it means that you are using an older version of Qt. Make sure that you are using Qt 3.2.0 or a later Qt 3 release. 8 1. Getting Started passed to the QSlider’s setValue(int) slot, which sets the slider value to 35.The slider then emits the valueChanged(int) signal, because its own value changed, triggering the spin box’s setValue(int) slot. But at this point, setValue(int) doesn’t emit any signal, since the spin box value is already 35. This prevents infinite recursion. Figure 1.6 summarizes the situation.

1. 00 ¤ S SSSSSSSSSSSSS

setValue(35)

2. 35 ¤ S SSSSSSSSSSSSS valueChanged(35)

setValue(35)

3. 35 ¤ SSSS S SSSSSSSSS valueChanged(35)

setValue(35)

4. 35 ¤ SSSS S SSSSSSSSS

Figure 1.6. Changing one value changes both

Line 22 shows the QHBox and its two child widgets. Qt’s approach to building user interfaces is simple to understand and very flex- ible. The most common pattern that Qt programmers use is to instantiate the required widgets and then set their propertiesas necessary. Programmersadd the widgetsto layouts,which automatically take care of sizing and positioning. User interface behavior is managed by connecting widgets together using Qt’s signals and slots mechanism.

Using the Reference Documentation

Qt’s reference documentation is an essential tool for any Qt developer, since it covers every class and function in Qt. (Qt 3.2 includes over 400 public classes and over 6000 functions.) This book makes use of many Qt classes and functions, but it doesn’t mention them all, nor does it provide all the details of those it does mention. To get the most benefit from Qt, you should familiarize yourself with the Qt reference documentation. Using the Reference Documentation 9

Widget Styles The screenshots we have seen so far have been taken on Windows XP, but Qt applications look native on every supported platform. Qt achieves this by emulating the platform’s , rather than wrapping a particular platform or toolkit’s widget set.

Windows Motif

MotifPlus CDE

Platinum SGI

Figure 1.7. Styles available everywhere

Qt application users can override the default style by using the -style command-line option. For example, to launch the Age application with Platinum style on Unix, simply type ./age -style=Platinum

on the command line.

Windows XP Mac

Figure 1.8. Platform-specific styles

Unlike the other styles, the Windows XP and Mac styles are only available on their native platforms, since they rely on the platforms’ theme engines.

The documentation is available in HTML format in Qt’s doc\html directo- ry and can be read using any web browser. You can also use Qt Assistant, the Qt help browser, whose powerful search and indexing features make it quicker and easier to use than a web browser. To launch Qt Assistant,click Qt 3.2.x|Qt Assistant in the Start on Windows, type assistant on the com- mand line on Unix, or double-click assistant in the Mac OS X Finder. 10 1. Getting Started

Figure 1.9. Qt’s documentation in Qt Assistant

The links in the “API Reference” section on the home page provide different ways of navigating Qt’s classes. The “All Classes” page lists every class in Qt’s API. The “Main Classes” page lists only the most commonly used Qt classes. As an exercise, you might want to look up the classes and functions that we have used in this chapter. Note that inherited functions are documented in the base class; for example, QPushButton has no show() function of its own, but it inherits one from its ancestor QWidget.Figure 1.10 shows how the classes we have seen so far relate to each other.

Qt

QObject

QApplication QWidget

QButton QFrame QSlider QSpinBox

QPushButton QHBox QLabel

Figure 1.10. Inheritance tree for the Qt classes seen so far

The reference documentation for the current version of Qt and for some earlier versions is available online at http://doc.trolltech.com/. This site also hosts selected articles from Qt Quarterly, the Qt programmers’ newsletter sent to all commercial licensees.