1 /****************************************************************************
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
6 ** This file is part of the documentation of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
17 ** GNU Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file. Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
26 ****************************************************************************/
29 \example mainwindows/application
30 \title Application Example
32 \brief The Application example shows how to implement a standard GUI
33 application with menus, toolbars, and a status bar. The example
34 itself is a simple text editor program built around QPlainTextEdit.
36 \image application.png Screenshot of the Application example
38 Nearly all of the code for the Application example is in the \c
39 MainWindow class, which inherits QMainWindow. QMainWindow
40 provides the framework for windows that have menus, toolbars,
41 dock windows, and a status bar. The application provides
42 \menu{File}, \menu{Edit}, and \menu{Help} entries in the menu
43 bar, with the following popup menus:
45 \image application-menus.png The Application example's menu system
47 The status bar at the bottom of the main window shows a
48 description of the menu item or toolbar button under the cursor.
50 To keep the example simple, recently opened files aren't shown in
51 the \menu{File} menu, even though this feature is desired in 90%
52 of applications. The \l{mainwindows/recentfiles}{Recent Files}
53 example shows how to implement this. Furthermore, this example
54 can only load one file at a time. The \l{mainwindows/sdi}{SDI}
55 and \l{mainwindows/mdi}{MDI} examples shows how to lift these
58 \section1 MainWindow Class Definition
60 Here's the class definition:
62 \snippet examples/mainwindows/application/mainwindow.h 0
64 The public API is restricted to the constructor. In the \c
65 protected section, we reimplement QWidget::closeEvent() to detect
66 when the user attempts to close the window, and warn the user
67 about unsaved changes. In the \c{private slots} section, we
68 declare slots that correspond to menu entries, as well as a
69 mysterious \c documentWasModified() slot. Finally, in the \c
70 private section of the class, we have various members that will
71 be explained in due time.
73 \section1 MainWindow Class Implementation
75 \snippet examples/mainwindows/application/mainwindow.cpp 0
77 We start by including \c <QtGui>, a header file that contains the
78 definition of all classes in the \l QtCore and \l QtGui
79 libraries. This saves us from the trouble of having to include
80 every class individually. We also include \c mainwindow.h.
82 You might wonder why we don't include \c <QtGui> in \c
83 mainwindow.h and be done with it. The reason is that including
84 such a large header from another header file can rapidly degrade
85 performances. Here, it wouldn't do any harm, but it's still
86 generally a good idea to include only the header files that are
87 strictly necessary from another header file.
89 \snippet examples/mainwindows/application/mainwindow.cpp 1
90 \snippet examples/mainwindows/application/mainwindow.cpp 2
92 In the constructor, we start by creating a QPlainTextEdit widget as a
93 child of the main window (the \c this object). Then we call
94 QMainWindow::setCentralWidget() to tell that this is going to be
95 the widget that occupies the central area of the main window,
96 between the toolbars and the status bar.
98 Then we call \c createActions(), \c createMenus(), \c
99 createToolBars(), and \c createStatusBar(), four private
100 functions that set up the user interface. After that, we call \c
101 readSettings() to restore the user's preferences.
103 We establish a signal-slot connection between the QPlainTextEdit's
104 document object and our \c documentWasModified() slot. Whenever
105 the user modifies the text in the QPlainTextEdit, we want to update
106 the title bar to show that the file was modified.
108 At the end, we set the window title using the private
109 \c setCurrentFile() function. We'll come back to this later.
111 \target close event handler
112 \snippet examples/mainwindows/application/mainwindow.cpp 3
113 \snippet examples/mainwindows/application/mainwindow.cpp 4
115 When the user attempts to close the window, we call the private
116 function \c maybeSave() to give the user the possibility to save
117 pending changes. The function returns true if the user wants the
118 application to close; otherwise, it returns false. In the first
119 case, we save the user's preferences to disk and accept the close
120 event; in the second case, we ignore the close event, meaning
121 that the application will stay up and running as if nothing
124 \snippet examples/mainwindows/application/mainwindow.cpp 5
125 \snippet examples/mainwindows/application/mainwindow.cpp 6
127 The \c newFile() slot is invoked when the user selects
128 \menu{File|New} from the menu. We call \c maybeSave() to save any
129 pending changes and if the user accepts to go on, we clear the
130 QPlainTextEdit and call the private function \c setCurrentFile() to
131 update the window title and clear the
132 \l{QWidget::windowModified}{windowModified} flag.
134 \snippet examples/mainwindows/application/mainwindow.cpp 7
135 \snippet examples/mainwindows/application/mainwindow.cpp 8
137 The \c open() slot is invoked when the user clicks
138 \menu{File|Open}. We pop up a QFileDialog asking the user to
139 choose a file. If the user chooses a file (i.e., \c fileName is
140 not an empty string), we call the private function \c loadFile()
141 to actually load the file.
143 \snippet examples/mainwindows/application/mainwindow.cpp 9
144 \snippet examples/mainwindows/application/mainwindow.cpp 10
146 The \c save() slot is invoked when the user clicks
147 \menu{File|Save}. If the user hasn't provided a name for the file
148 yet, we call \c saveAs(); otherwise, we call the private function
149 \c saveFile() to actually save the file.
151 \snippet examples/mainwindows/application/mainwindow.cpp 11
152 \snippet examples/mainwindows/application/mainwindow.cpp 12
154 In \c saveAs(), we start by popping up a QFileDialog asking the
155 user to provide a name. If the user clicks \gui{Cancel}, the
156 returned file name is empty, and we do nothing.
158 \snippet examples/mainwindows/application/mainwindow.cpp 13
159 \snippet examples/mainwindows/application/mainwindow.cpp 14
161 The application's About box is done using one statement, using
162 the QMessageBox::about() static function and relying on its
163 support for an HTML subset.
165 The \l{QObject::tr()}{tr()} call around the literal string marks
166 the string for translation. It is a good habit to call
167 \l{QObject::tr()}{tr()} on all user-visible strings, in case you
168 later decide to translate your application to other languages.
169 The \l{Internationalization with Qt} overview convers
170 \l{QObject::tr()}{tr()} in more detail.
172 \snippet examples/mainwindows/application/mainwindow.cpp 15
173 \snippet examples/mainwindows/application/mainwindow.cpp 16
175 The \c documentWasModified() slot is invoked each time the text
176 in the QPlainTextEdit changes because of user edits. We call
177 QWidget::setWindowModified() to make the title bar show that the
178 file was modified. How this is done varies on each platform.
180 \snippet examples/mainwindows/application/mainwindow.cpp 17
181 \snippet examples/mainwindows/application/mainwindow.cpp 18
183 \snippet examples/mainwindows/application/mainwindow.cpp 22
185 The \c createActions() private function, which is called from the
186 \c MainWindow constructor, creates \l{QAction}s. The code is very
187 repetitive, so we show only the actions corresponding to
188 \menu{File|New}, \menu{File|Open}, and \menu{Help|About Qt}.
190 A QAction is an object that represents one user action, such as
191 saving a file or invoking a dialog. An action can be put in a
192 QMenu or a QToolBar, or both, or in any other widget that
193 reimplements QWidget::actionEvent().
195 An action has a text that is shown in the menu, an icon, a
196 shortcut key, a tooltip, a status tip (shown in the status bar),
197 a "What's This?" text, and more. It emits a
198 \l{QAction::triggered()}{triggered()} signal whenever the user
199 invokes the action (e.g., by clicking the associated menu item or
200 toolbar button). We connect this signal to a slot that performs
203 The code above contains one more idiom that must be explained.
204 For some of the actions, we specify an icon as a QIcon to the
205 QAction constructor. The QIcon constructor takes the file name
206 of an image that it tries to load. Here, the file name starts
207 with \c{:}. Such file names aren't ordinary file names, but
208 rather path in the executable's stored resources. We'll come back
209 to this when we review the \c application.qrc file that's part of
212 \snippet examples/mainwindows/application/mainwindow.cpp 23
213 \snippet examples/mainwindows/application/mainwindow.cpp 24
215 The \gui{Edit|Cut} and \gui{Edit|Copy} actions must be available
216 only when the QPlainTextEdit contains selected text. We disable them
217 by default and connect the QPlainTextEdit::copyAvailable() signal to
218 the QAction::setEnabled() slot, ensuring that the actions are
219 disabled when the text editor has no selection.
221 \snippet examples/mainwindows/application/mainwindow.cpp 25
222 \snippet examples/mainwindows/application/mainwindow.cpp 27
224 Creating actions isn't sufficient to make them available to the
225 user; we must also add them to the menu system. This is what \c
226 createMenus() does. We create a \menu{File}, an \menu{Edit}, and
227 a \menu{Help} menu. QMainWindow::menuBar() lets us access the
228 window's menu bar widget. We don't have to worry about creating
229 the menu bar ourselves; the first time we call this function, the
232 Just before we create the \menu{Help} menu, we call
233 QMenuBar::addSeparator(). This has no effect for most widget
234 styles (e.g., Windows and Mac OS X styles), but for Motif-based
235 styles this makes sure that \menu{Help} is pushed to the right
236 side of the menu bar. Try running the application with various
237 styles and see the results:
239 \snippet doc/src/snippets/code/doc_src_examples_application.qdoc 0
241 Let's now review the toolbars:
243 \snippet examples/mainwindows/application/mainwindow.cpp 30
245 Creating toolbars is very similar to creating menus. The same
246 actions that we put in the menus can be reused in the toolbars.
248 \snippet examples/mainwindows/application/mainwindow.cpp 32
249 \snippet examples/mainwindows/application/mainwindow.cpp 33
251 QMainWindow::statusBar() returns a pointer to the main window's
252 QStatusBar widget. Like with \l{QMainWindow::menuBar()}, the
253 widget is automatically created the first time the function is
256 \snippet examples/mainwindows/application/mainwindow.cpp 34
257 \snippet examples/mainwindows/application/mainwindow.cpp 36
259 The \c readSettings() function is called from the constructor to
260 load the user's preferences and other application settings. The
261 QSettings class provides a high-level interface for storing
262 settings permanently on disk. On Windows, it uses the (in)famous
263 Windows registry; on Mac OS X, it uses the native XML-based
264 CFPreferences API; on Unix/X11, it uses text files.
266 The QSettings constructor takes arguments that identify your
267 company and the name of the product. This ensures that the
268 settings for different applications are kept separately.
270 We use QSettings::value() to extract the value of the "pos" and
271 "size" settings. The second argument to QSettings::value() is
272 optional and specifies a default value for the setting if there
273 exists none. This value is used the first time the application is
276 When restoring the position and size of a window, it's important
277 to call QWidget::resize() before QWidget::move(). The reason why
278 is given in the \l{Window Geometry} overview.
280 \snippet examples/mainwindows/application/mainwindow.cpp 37
281 \snippet examples/mainwindows/application/mainwindow.cpp 39
283 The \c writeSettings() function is called from \c closeEvent().
284 Writing settings is similar to reading them, except simpler. The
285 arguments to the QSettings constructor must be the same as in \c
288 \snippet examples/mainwindows/application/mainwindow.cpp 40
289 \snippet examples/mainwindows/application/mainwindow.cpp 41
291 The \c maybeSave() function is called to save pending changes. If
292 there are pending changes, it pops up a QMessageBox giving the
293 user to save the document. The options are QMessageBox::Yes,
294 QMessageBox::No, and QMessageBox::Cancel. The \gui{Yes} button is
295 made the default button (the button that is invoked when the user
296 presses \key{Return}) using the QMessageBox::Default flag; the
297 \gui{Cancel} button is made the escape button (the button that is
298 invoked when the user presses \key{Esc}) using the
299 QMessageBox::Escape flag.
301 The \c maybeSave() function returns \c true in all cases, except
302 when the user clicks \gui{Cancel}. The caller must check the
303 return value and stop whatever it was doing if the return value
306 \snippet examples/mainwindows/application/mainwindow.cpp 42
307 \snippet examples/mainwindows/application/mainwindow.cpp 43
309 In \c loadFile(), we use QFile and QTextStream to read in the
310 data. The QFile object provides access to the bytes stored in a
313 We start by opening the file in read-only mode. The QFile::Text
314 flag indicates that the file is a text file, not a binary file.
315 On Unix and Mac OS X, this makes no difference, but on Windows,
316 it ensures that the "\\r\\n" end-of-line sequence is converted to
319 If we successfully opened the file, we use a QTextStream object
320 to read in the data. QTextStream automatically converts the 8-bit
321 data into a Unicode QString and supports various encodings. If no
322 encoding is specified, QTextStream assumes the file is written
323 using the system's default 8-bit encoding (for example, Latin-1;
324 see QTextCodec::codecForLocale() for details).
326 Since the call to QTextStream::readAll() might take some time, we
327 set the cursor to be Qt::WaitCursor for the entire application
330 At the end, we call the private \c setCurrentFile() function,
331 which we'll cover in a moment, and we display the string "File
332 loaded" in the status bar for 2 seconds (2000 milliseconds).
334 \snippet examples/mainwindows/application/mainwindow.cpp 44
335 \snippet examples/mainwindows/application/mainwindow.cpp 45
337 Saving a file is very similar to loading one. Here, the
338 QFile::Text flag ensures that on Windows, "\\n" is converted into
339 "\\r\\n" to conform to the Windows convension.
341 \snippet examples/mainwindows/application/mainwindow.cpp 46
342 \snippet examples/mainwindows/application/mainwindow.cpp 47
344 The \c setCurrentFile() function is called to reset the state of
345 a few variables when a file is loaded or saved, or when the user
346 starts editing a new file (in which case \c fileName is empty).
347 We update the \c curFile variable, clear the
348 QTextDocument::modified flag and the associated \c
349 QWidget:windowModified flag, and update the window title to
350 contain the new file name (or \c untitled.txt).
352 The \c strippedName() function call around \c curFile in the
353 QWidget::setWindowTitle() call shortens the file name to exclude
354 the path. Here's the function:
356 \snippet examples/mainwindows/application/mainwindow.cpp 48
357 \snippet examples/mainwindows/application/mainwindow.cpp 49
359 \section1 The main() Function
361 The \c main() function for this application is typical of
362 applications that contain one main window:
364 \snippet examples/mainwindows/application/main.cpp 0
366 \section1 The Resource File
368 As you will probably recall, for some of the actions, we
369 specified icons with file names starting with \c{:} and mentioned
370 that such file names aren't ordinary file names, but path in the
371 executable's stored resources. These resources are compiled
373 The resources associated with an application are specified in a
374 \c .qrc file, an XML-based file format that lists files on the
375 disk. Here's the \c application.qrc file that's used by the
378 \quotefile mainwindows/application/application.qrc
380 The \c .png files listed in the \c application.qrc file are files
381 that are part of the Application example's source tree. Paths are
382 relative to the directory where the \c application.qrc file is
383 located (the \c mainwindows/application directory).
385 The resource file must be mentioned in the \c application.pro
386 file so that \c qmake knows about it:
388 \snippet examples/mainwindows/application/application.pro 0
390 \c qmake will produce make rules to generate a file called \c
391 qrc_application.cpp that is linked into the application. This
392 file contains all the data for the images and other resources as
393 static C++ arrays of compressed binary data. See
394 \l{resources.html}{The Qt Resource System} for more information