• Aucun résultat trouvé

Deriving from QMainWindow

Dans le document Qt 4 THE BOOK of THE BOOK of (Page 105-108)

Developing a GUI Application Based on a Main Window

4.2 Deriving from QMainWindow

More serious applications usually inherit from QMainWindow, adding features that provide more control. In contrast to the above example, we shall derive a separate class called MainWindow from QMainWindow, on the basis of which we shall con-struct CuteEdit. At the same time we will get to know other essential widgets, such as QTextEdit, a flexible editor widget.

// cuteedit1/main.cpp

#include <QApplication>

#include "mainwindow.h"

int main(int argc, char *argv[]) {

QApplication a(argc, argv);

MainWindow mainWindow;

mainWindow.show();

return a.exec();

}

The main() function is almost identical to the one from our “Hello, world!” pro-gram from Section 1.1. Instead of the QMainWindow class from the mainwin-dow example on page 102, we now use our own MainWinmainwin-dow class, derived from QMainWindow. The corresponding class definition can be found in the header file mainwindow.h.2 The #include directive which incorporates the contents of this header file uses quotation marks instead of angle brackets, since the file is not a standard header file.

We again surround the file contents of mainwindow.h with an #ifdef construction providing theinclude guardsto avoid compilation errors if this header file is in-cluded by more than one source file.3 MAINWINDOW_H will be defined when the header file is processed for the first time, and the preprocessor ignores the entire file contents for all subsequent inclusion attempts:

// cuteedit1/mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow {

Q_OBJECT public:

MainWindow();

};

#endif // MAINWINDOW_H

Since the MainWindow class is derived from QMainWindow, we first issue a di-rective to include the header file for the QMainWindow class. To ensure that the QMainWindow methods remain accessible even outside the MainWindow class, we grant the derivation public access.

Because our new class also inherits from QObject as a base class, we must not forget the Q_OBJECT macro. Otherwise the linker will complain of undefined symbols, which, in the case of self-defined signals, results in an error message. In the case of a Tool class, which defines a signal called switchTool(Tool*), this will appear as follows:

tool.o: In function ‘Tool::activateTool(bool)’:

tool.cpp:(.text+0x5f): undefined reference to ‘Tool::switchTool(Tool*)’

collect2: ld returned status 1

2 For header files that we create ourselves, we use the filename extension common in C/C++, .h, to make clear the file type. We do not use uppercase in any filenames.

3 See page 62.

In the MainWindow class itself, we only have to define the constructor. For this reason, the source text file mainwindow.cpp is also rather short:

// cuteedit1/mainwindow.cpp

QLabel* label = new QLabel(tr("Central Widget"));

setCentralWidget(label);

label->setAlignment(Qt::AlignCenter);

}

In the constructor we the first call the QWidget function setWindowTitle(). Since the MainWindow class is derived from QWidget as the base class, it inherits this function, and we can use it to set the text displayed by the title bar of the window.

If you leave this step out, Qt uses the program name as the title text.

We set the text for the title bar via the tr() method, which inherits MainWindow inherits from QObject. If the user wants, this will translate the text to another language at runtime; if not, it returns the string unchanged.4

The resize() function that MainWindow also inherits from QWidget specifies the size of the window. The two arguments determine the width and height of the window in pixels. If the size is not set explicitly, Qt will determine it automatically, based on the content to be displayed. But in our case this would be too small, since we will soon fill the window with more content.

In order to display something in the main window, we create a QLabel object with the central widget text and make it the focal point of the application with the set-CentralWidget() function, which MainWindow inherits from QMainWindow. With this call the MainWindow object adopts the new QLabel. Accordingly we must al-locate it on the heap with new, from which it will ultimately be deleted by the memory management provided by Qt for instances of QObject.

The setCentralWidget() call packs the QLabel object into a layout so that it fills the entire space in the window. By default the QLabel class arranges text centered ver-tically, and horizontally aligned at the left margin. To center text in both directions, we change the alignment with setAlignment(). This function takes as an argument values from the enumeration type (enum) alignment, which is defined in the Qt namespace5—hence the value AlignCenter is prefixed with Qt::.

4 See also page 49 and Chapter 14 from page 375 for a detailed discussion.

5 Qt uses the namespace Qt for a large number of enumeration types, in order to avoid conflicts when the same symbolic names are used in several contexts.

So that qmake can unite the existing files into a project, we use the following .pro file:

#cuteedit1/cuteedit1.pro TEMPLATE = app

SOURCES = main.cpp mainwindow.cpp HEADERS = mainwindow.h

FORMS = mainwindow.ui

Apart from the already known variables TEMPLATE and SOURCES, which we use to specify that we are compiling an application and to specify the source text files, the HEADERS variable is also used. This specifies the header files to be used in the project: qmake searches through those header files for the Q_OBJECT macro and creates appropriate rules for the moc calls.

Dans le document Qt 4 THE BOOK of THE BOOK of (Page 105-108)