Getting Started Programming With QT 5 Widgets
Getting Started Programming With QT 5 Widgets
You can find the final Notepad source files in the qtdoc repository in the doc/src/snippets/widgets-tutorial/notepad directory. You can either fetch the Qt 5 sources from Qt Project or install them as part of Qt 5.
To create the Notepad project, select File > New File or Project > Applications > Qt Gui Application > Choose, and follow the instructions of the wizard. In the Class Information dialog, type Notepad as the class name and select QMainWindow as the base class.
The Qt Gui Application wizard creates a project that contains a main source file and a set of files that specify a user interface (Notepad widget): notepad.pro - the project file. main.cpp - the main source file for the application. notepad.cpp - the source file of the notepad class of the Notepad widget. 2
The .cpp, .h, and .ui files come with the necessary boiler plate code for you to be able to build and run the project. The .pro file is complete. We will take a closer look at the file contents in the following sections.
Learn More
About Using Qt Creator Here Qt Creator
#include "notepad.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Notepad w; w.show(); return a.exec(); } Let us go through the code line by line. On the first two lines, we include the header files for the Notepad widget and QApplication. All Qt classes have a header file named after them. Line 4 defines the main function that is the entry point for all C and C++ based applications. Line 6 creates a QApplication object. This object manages application-wide resources and is necessary to run any Qt program that uses Qt Widgets. It constructs an application object with argc command line arguments run in argv. (For GUI applications that do not use Qt Widgets, you can use QGuiApplication instead.) Line 7 creates the Notepad object. This is the object for which the wizard created the class and the UI file. The user interface contains visual elements that are called widgets in Qt. Examples of widgets are text edits, scroll bars, labels, and radio buttons. A widget can also be a container for other widgets; a dialog or a main application window, for example. Line 8 shows the Notepad widget on the screen in its own window. Since widgets also function as containers (for instance a QMainWindow, which has toolbars, menus, a status bar, and a few other widgets), it is possible to show a single widget in its own window. Widgets are not visible by default; the function show() makes the widget visible. Line 10 makes the QApplication enter its event loop. When a Qt application is running, events are generated and sent to the widgets of the application. Examples of events are mouse presses and key strokes.
Learn More
About Events and event handling Here The Event System Widgets and Window Geometry Window and Dialog Widgets
Designing a UI
The wizard generates a user interface definition in XML format, notepad.ui. When you open the notepad.ui file in Qt Creator, it automatically opens in the integrated Qt Designer. When you build the application, Qt Creator launches the Qt User Interface Compiler (uic) that reads the .ui file and creates a corresponding C++ header file, ui_notepad.h. 4
Using Qt Designer
The wizard creates an application that uses a QMainWindow. It has its own layout to which you can add a menu bar, dock widgets, tool bars, and a status bar. The center area can be occupied by any kind of widget. The wizard places the Notepad widget there. Let us use Qt Designer to add a QTextEdit object and a QPushButton object to the main window. When you type text in the text edit widget, it receives key pressed events and responds by drawing the text typed. The button will exit the Notepad application when pushed (that is, clicked with the mouse). To add widgets in Qt Designer: 1. In the Qt Creator Editor mode, double-click the notepad.ui file in the Projects view to launch the file in the integrated Qt Designer. 2. Drag and drop the following widgets to the form: o Text Edit (QTextEdit) o Push Button (QPushButton) 3. Double-click the Push Button widget and enter the text Quit. 4. In the Properties pane, change the value of objectName to quitButton. 5. Press Ctrl+A (or Cmd+A) to select the widgets and click Lay out Vertically (or press Ctrl+L) to apply a vertical layout (QVBoxLayout). 6. Press Ctrl+S (or Cmd+S) to save your changes. The UI now looks as follows in Qt Designer:
You can view the generated XML file in the code editor: <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Notepad</class> <widget class="QMainWindow" name="Notepad"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> 5
Project File
The wizard generates the following project file, notepad.pro, for us: QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Notepad TEMPLATE = app SOURCES += main.cpp\ notepad.cpp HEADERS FORMS += notepad.h += notepad.ui
The project file specifies the application name and the qmake template to use for generating the project, as well as the source, header, and UI files included in the project.
Learn More
About Using Qt Designer Layouts The widgets that come with Qt Main windows and main window classes QObjects and the Qt Object model (This is essential to understand Qt) qmake and the Qt build system Here Qt Designer Manual Layout Management, Widgets and Layouts, Layout Examples Qt Widget Gallery Application Main Window, Main Window Examples Object Model qmake Manual
11
Learn More
About Here Signals and slots Signals & Slots
To connect the actions to slots, right-click an action and select Go to slot > triggered(). QAction instances are created with the text that should appear on the widgets that we add them to (in our case, menu items). If we also wanted to add the actions to a tool bar, we could have specified icons for them. The modified code in notepad.ui now looks as follows: <widget class="QMenuBar" name="menuBar"> 13
Opening Files
In this section, we implement the functionality of the on_actionOpen_triggered() slot. The first step is asking the user for the name of the file to open. Qt comes with QFileDialog, which is a dialog from which the user can select a file. The appearance of the dialog depends on the desktop platform that you run the application on. The following image shows the dialog on Mac OS:
14
We complement the code generated by Qt Designer in notepad.cpp, as follows: void Notepad::on_actionOpen_triggered() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("Text Files (*.txt);;C++ Files (*.cpp *.h)")); if (!fileName.isEmpty()) { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(this, tr("Error"), tr("Could not open file")); return; } QTextStream in(&file); ui->textEdit->setText(in.readAll()); file.close(); } } The static getOpenFileName() function displays a modal file dialog. It returns the file path of the file selected, or an empty string if the user canceled the dialog. If we have a file name, we try to open the file with open(), which returns true if the file could be opened. We will not go into error handling here, but you can follow the links from the learn more section. If the file could not be opened, we use QMessageBox to display a dialog with an error message (see the QMessageBox class description for further details). Actually reading in the data is trivial using the QTextStream class, which wraps the QFile object. The readAll() function returns the contents of the file as a QString. The contents can then be displayed in the text edit. We then close() the file to return the file descriptor back to the operating system.
15
Saving Files
Now, let us move on to the on_actionSave_triggered() slot, which also uses QFileDialog to create a dialog in which the user can save a file with the specified name in the specified location.
We complement the code generated by Qt Designer in notepad.cpp, as follows: void Notepad::on_actionSave_triggered() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), QString(), tr("Text Files (*.txt);;C++ Files (*.cpp *.h)")); if (!fileName.isEmpty()) { QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { // error message } else { QTextStream stream(&file); stream << ui->textEdit->toPlainText(); stream.flush(); file.close(); } } } When we write the contents of the text edit to the file, we use the QTextStream class again. QTextStream can also write QStrings to the file with the << operator.
16
Learn More
About MDI applications Files and I/O devices tr() and internationalization QMdiArea, MDI Example QFile, QIODevice Qt Linguist Manual, Writing Source Code for Translation, Internationalization with Qt Here
17