source: trunk/doc/src/examples/application.qdoc@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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