Implementing the AddressBook Class
The constructor of AddressBook accepts a QWidget parameter, parent. By convention, we pass this parameter to the base class's constructor. This concept of ownership, where a parent can have one or more children, is useful for grouping widgets in Qt. For example, if you delete a parent, all of its children will be deleted as well.
AddressBook::AddressBook(QWidget *parent)
: QWidget(parent)
{
QLabel *nameLabel = new QLabel(tr("Name:"));
nameLine = new QLineEdit;
QLabel *addressLabel = new QLabel(tr("Address:"));
addressText = new QTextEdit;
Within this constructor, we declare and instantiate two local QLabel objects, nameLabel and addressLabel, as well as instantiate nameLine and addressText. The tr() function returns a translated version of the string, if there is one available; otherwise, it returns the string itself. Think of this function as an <insert translation here> marker to mark QString objects for translation. You will notice, in the coming chapters as well as in the Qt Examples, that we include it whenever we use a translatable string.
When programming with Qt, it is useful to know how layouts work. Qt provides three main layout classes: QHBoxLayout, QVBoxLayout and QGridLayout to handle the positioning of widgets.
We use a QGridLayout to position our labels and input fields in a structured manner. QGridLayout divides the available space into a grid and places widgets in the cells we specify with row and column numbers. The diagram above shows the layout cells and the position of our widgets, and we specify this arrangement using the following code:
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(nameLabel, 0, 0);
mainLayout->addWidget(nameLine, 0, 1);
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
mainLayout->addWidget(addressText, 1, 1);
Notice that addressLabel is positioned using Qt::AlignTop as an additional argument. This is to make sure it is not vertically centered in cell (1,0). For a basic overview on Qt Layouts, refer to the Layout Management documentation.
In order to install the layout object onto the widget, we have to invoke the widget's setLayout() function:
setLayout(mainLayout);
setWindowTitle(tr("Simple Address Book"));
}
Lastly, we set the widget's title to "Simple Address Book".
Running the Application
A separate file, main.cpp, is used for the main() function. Within this function, we instantiate a QApplication object, app. QApplication is responsible for various application-wide resources, such as the default font and cursor, and for running an event loop. Hence, there is always one QApplication object in every GUI application using Qt.
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
AddressBook addressBook;
addressBook.show();
return app.exec();
}
We construct a new AddressBook widget on the stack and invoke its show() function to display it. However, the widget will not be shown until the application's event loop is started. We start the event loop by calling the application's exec() function; the result returned by this function is used as the return value from the main() function. At this point, it becomes apparent why we instanciated AddressBook on the stack: It will now go out of scope. Therefore, AddressBook and all its child widgets will be deleted, thus preventing memory leaks.
[Contents]
[Next: Chapter 2]