diff -r 000000000000 -r 1918ee327afb doc/src/examples/application.qdoc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/examples/application.qdoc Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,410 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/application + \title Application Example + + The Application example shows how to implement a standard GUI + application with menus, toolbars, and a status bar. The example + itself is a simple text editor program built around QPlainTextEdit. + + \image application.png Screenshot of the Application example + + Nearly all of the code for the Application example is in the \c + MainWindow class, which inherits QMainWindow. QMainWindow + provides the framework for windows that have menus, toolbars, + dock windows, and a status bar. The application provides + \menu{File}, \menu{Edit}, and \menu{Help} entries in the menu + bar, with the following popup menus: + + \image application-menus.png The Application example's menu system + + The status bar at the bottom of the main window shows a + description of the menu item or toolbar button under the cursor. + + To keep the example simple, recently opened files aren't shown in + the \menu{File} menu, even though this feature is desired in 90% + of applications. The \l{mainwindows/recentfiles}{Recent Files} + example shows how to implement this. Furthermore, this example + can only load one file at a time. The \l{mainwindows/sdi}{SDI} + and \l{mainwindows/mdi}{MDI} examples shows how to lift these + restrictions. + + \section1 MainWindow Class Definition + + Here's the class definition: + + \snippet examples/mainwindows/application/mainwindow.h 0 + + The public API is restricted to the constructor. In the \c + protected section, we reimplement QWidget::closeEvent() to detect + when the user attempts to close the window, and warn the user + about unsaved changes. In the \c{private slots} section, we + declare slots that correspond to menu entries, as well as a + mysterious \c documentWasModified() slot. Finally, in the \c + private section of the class, we have various members that will + be explained in due time. + + \section1 MainWindow Class Implementation + + \snippet examples/mainwindows/application/mainwindow.cpp 0 + + We start by including \c , a header file that contains the + definition of all classes in the \l QtCore and \l QtGui + libraries. This saves us from the trouble of having to include + every class individually. We also include \c mainwindow.h. + + You might wonder why we don't include \c in \c + mainwindow.h and be done with it. The reason is that including + such a large header from another header file can rapidly degrade + performances. Here, it wouldn't do any harm, but it's still + generally a good idea to include only the header files that are + strictly necessary from another header file. + + \snippet examples/mainwindows/application/mainwindow.cpp 1 + \snippet examples/mainwindows/application/mainwindow.cpp 2 + + In the constructor, we start by creating a QPlainTextEdit widget as a + child of the main window (the \c this object). Then we call + QMainWindow::setCentralWidget() to tell that this is going to be + the widget that occupies the central area of the main window, + between the toolbars and the status bar. + + Then we call \c createActions(), \c createMenus(), \c + createToolBars(), and \c createStatusBar(), four private + functions that set up the user interface. After that, we call \c + readSettings() to restore the user's preferences. + + We establish a signal-slot connection between the QPlainTextEdit's + document object and our \c documentWasModified() slot. Whenever + the user modifies the text in the QPlainTextEdit, we want to update + the title bar to show that the file was modified. + + At the end, we set the window title using the private + \c setCurrentFile() function. We'll come back to this later. + + \target close event handler + \snippet examples/mainwindows/application/mainwindow.cpp 3 + \snippet examples/mainwindows/application/mainwindow.cpp 4 + + When the user attempts to close the window, we call the private + function \c maybeSave() to give the user the possibility to save + pending changes. The function returns true if the user wants the + application to close; otherwise, it returns false. In the first + case, we save the user's preferences to disk and accept the close + event; in the second case, we ignore the close event, meaning + that the application will stay up and running as if nothing + happened. + + \snippet examples/mainwindows/application/mainwindow.cpp 5 + \snippet examples/mainwindows/application/mainwindow.cpp 6 + + The \c newFile() slot is invoked when the user selects + \menu{File|New} from the menu. We call \c maybeSave() to save any + pending changes and if the user accepts to go on, we clear the + QPlainTextEdit and call the private function \c setCurrentFile() to + update the window title and clear the + \l{QWidget::windowModified}{windowModified} flag. + + \snippet examples/mainwindows/application/mainwindow.cpp 7 + \snippet examples/mainwindows/application/mainwindow.cpp 8 + + The \c open() slot is invoked when the user clicks + \menu{File|Open}. We pop up a QFileDialog asking the user to + choose a file. If the user chooses a file (i.e., \c fileName is + not an empty string), we call the private function \c loadFile() + to actually load the file. + + \snippet examples/mainwindows/application/mainwindow.cpp 9 + \snippet examples/mainwindows/application/mainwindow.cpp 10 + + The \c save() slot is invoked when the user clicks + \menu{File|Save}. If the user hasn't provided a name for the file + yet, we call \c saveAs(); otherwise, we call the private function + \c saveFile() to actually save the file. + + \snippet examples/mainwindows/application/mainwindow.cpp 11 + \snippet examples/mainwindows/application/mainwindow.cpp 12 + + In \c saveAs(), we start by popping up a QFileDialog asking the + user to provide a name. If the user clicks \gui{Cancel}, the + returned file name is empty, and we do nothing. + + \snippet examples/mainwindows/application/mainwindow.cpp 13 + \snippet examples/mainwindows/application/mainwindow.cpp 14 + + The application's About box is done using one statement, using + the QMessageBox::about() static function and relying on its + support for an HTML subset. + + The \l{QObject::tr()}{tr()} call around the literal string marks + the string for translation. It is a good habit to call + \l{QObject::tr()}{tr()} on all user-visible strings, in case you + later decide to translate your application to other languages. + The \l{Internationalization with Qt} overview convers + \l{QObject::tr()}{tr()} in more detail. + + \snippet examples/mainwindows/application/mainwindow.cpp 15 + \snippet examples/mainwindows/application/mainwindow.cpp 16 + + The \c documentWasModified() slot is invoked each time the text + in the QPlainTextEdit changes because of user edits. We call + QWidget::setWindowModified() to make the title bar show that the + file was modified. How this is done varies on each platform. + + \snippet examples/mainwindows/application/mainwindow.cpp 17 + \snippet examples/mainwindows/application/mainwindow.cpp 18 + \dots + \snippet examples/mainwindows/application/mainwindow.cpp 22 + + The \c createActions() private function, which is called from the + \c MainWindow constructor, creates \l{QAction}s. The code is very + repetitive, so we show only the actions corresponding to + \menu{File|New}, \menu{File|Open}, and \menu{Help|About Qt}. + + A QAction is an object that represents one user action, such as + saving a file or invoking a dialog. An action can be put in a + QMenu or a QToolBar, or both, or in any other widget that + reimplements QWidget::actionEvent(). + + An action has a text that is shown in the menu, an icon, a + shortcut key, a tooltip, a status tip (shown in the status bar), + a "What's This?" text, and more. It emits a + \l{QAction::triggered()}{triggered()} signal whenever the user + invokes the action (e.g., by clicking the associated menu item or + toolbar button). We connect this signal to a slot that performs + the actual action. + + The code above contains one more idiom that must be explained. + For some of the actions, we specify an icon as a QIcon to the + QAction constructor. The QIcon constructor takes the file name + of an image that it tries to load. Here, the file name starts + with \c{:}. Such file names aren't ordinary file names, but + rather path in the executable's stored resources. We'll come back + to this when we review the \c application.qrc file that's part of + the project. + + \snippet examples/mainwindows/application/mainwindow.cpp 23 + \snippet examples/mainwindows/application/mainwindow.cpp 24 + + The \gui{Edit|Cut} and \gui{Edit|Copy} actions must be available + only when the QPlainTextEdit contains selected text. We disable them + by default and connect the QPlainTextEdit::copyAvailable() signal to + the QAction::setEnabled() slot, ensuring that the actions are + disabled when the text editor has no selection. + + \snippet examples/mainwindows/application/mainwindow.cpp 25 + \snippet examples/mainwindows/application/mainwindow.cpp 27 + + Creating actions isn't sufficient to make them available to the + user; we must also add them to the menu system. This is what \c + createMenus() does. We create a \menu{File}, an \menu{Edit}, and + a \menu{Help} menu. QMainWindow::menuBar() lets us access the + window's menu bar widget. We don't have to worry about creating + the menu bar ourselves; the first time we call this function, the + QMenuBar is created. + + Just before we create the \menu{Help} menu, we call + QMenuBar::addSeparator(). This has no effect for most widget + styles (e.g., Windows and Mac OS X styles), but for Motif-based + styles this makes sure that \menu{Help} is pushed to the right + side of the menu bar. Try running the application with various + styles and see the results: + + \snippet doc/src/snippets/code/doc_src_examples_application.qdoc 0 + + Let's now review the toolbars: + + \snippet examples/mainwindows/application/mainwindow.cpp 30 + + Creating toolbars is very similar to creating menus. The same + actions that we put in the menus can be reused in the toolbars. + + \snippet examples/mainwindows/application/mainwindow.cpp 32 + \snippet examples/mainwindows/application/mainwindow.cpp 33 + + QMainWindow::statusBar() returns a pointer to the main window's + QStatusBar widget. Like with \l{QMainWindow::menuBar()}, the + widget is automatically created the first time the function is + called. + + \snippet examples/mainwindows/application/mainwindow.cpp 34 + \snippet examples/mainwindows/application/mainwindow.cpp 36 + + The \c readSettings() function is called from the constructor to + load the user's preferences and other application settings. The + QSettings class provides a high-level interface for storing + settings permanently on disk. On Windows, it uses the (in)famous + Windows registry; on Mac OS X, it uses the native XML-based + CFPreferences API; on Unix/X11, it uses text files. + + The QSettings constructor takes arguments that identify your + company and the name of the product. This ensures that the + settings for different applications are kept separately. + + We use QSettings::value() to extract the value of the "pos" and + "size" settings. The second argument to QSettings::value() is + optional and specifies a default value for the setting if there + exists none. This value is used the first time the application is + run. + + When restoring the position and size of a window, it's important + to call QWidget::resize() before QWidget::move(). The reason why + is given in the \l{Window Geometry} overview. + + \snippet examples/mainwindows/application/mainwindow.cpp 37 + \snippet examples/mainwindows/application/mainwindow.cpp 39 + + The \c writeSettings() function is called from \c closeEvent(). + Writing settings is similar to reading them, except simpler. The + arguments to the QSettings constructor must be the same as in \c + readSettings(). + + \snippet examples/mainwindows/application/mainwindow.cpp 40 + \snippet examples/mainwindows/application/mainwindow.cpp 41 + + The \c maybeSave() function is called to save pending changes. If + there are pending changes, it pops up a QMessageBox giving the + user to save the document. The options are QMessageBox::Yes, + QMessageBox::No, and QMessageBox::Cancel. The \gui{Yes} button is + made the default button (the button that is invoked when the user + presses \key{Return}) using the QMessageBox::Default flag; the + \gui{Cancel} button is made the escape button (the button that is + invoked when the user presses \key{Esc}) using the + QMessageBox::Escape flag. + + The \c maybeSave() function returns \c true in all cases, except + when the user clicks \gui{Cancel}. The caller must check the + return value and stop whatever it was doing if the return value + is \c false. + + \snippet examples/mainwindows/application/mainwindow.cpp 42 + \snippet examples/mainwindows/application/mainwindow.cpp 43 + + In \c loadFile(), we use QFile and QTextStream to read in the + data. The QFile object provides access to the bytes stored in a + file. + + We start by opening the file in read-only mode. The QFile::Text + flag indicates that the file is a text file, not a binary file. + On Unix and Mac OS X, this makes no difference, but on Windows, + it ensures that the "\\r\\n" end-of-line sequence is converted to + "\\n" when reading. + + If we successfully opened the file, we use a QTextStream object + to read in the data. QTextStream automatically converts the 8-bit + data into a Unicode QString and supports various encodings. If no + encoding is specified, QTextStream assumes the file is written + using the system's default 8-bit encoding (for example, Latin-1; + see QTextCodec::codecForLocale() for details). + + Since the call to QTextStream::readAll() might take some time, we + set the cursor to be Qt::WaitCursor for the entire application + while it goes on. + + At the end, we call the private \c setCurrentFile() function, + which we'll cover in a moment, and we display the string "File + loaded" in the status bar for 2 seconds (2000 milliseconds). + + \snippet examples/mainwindows/application/mainwindow.cpp 44 + \snippet examples/mainwindows/application/mainwindow.cpp 45 + + Saving a file is very similar to loading one. Here, the + QFile::Text flag ensures that on Windows, "\\n" is converted into + "\\r\\n" to conform to the Windows convension. + + \snippet examples/mainwindows/application/mainwindow.cpp 46 + \snippet examples/mainwindows/application/mainwindow.cpp 47 + + The \c setCurrentFile() function is called to reset the state of + a few variables when a file is loaded or saved, or when the user + starts editing a new file (in which case \c fileName is empty). + We update the \c curFile variable, clear the + QTextDocument::modified flag and the associated \c + QWidget:windowModified flag, and update the window title to + contain the new file name (or \c untitled.txt). + + The \c strippedName() function call around \c curFile in the + QWidget::setWindowTitle() call shortens the file name to exclude + the path. Here's the function: + + \snippet examples/mainwindows/application/mainwindow.cpp 48 + \snippet examples/mainwindows/application/mainwindow.cpp 49 + + \section1 The main() Function + + The \c main() function for this application is typical of + applications that contain one main window: + + \snippet examples/mainwindows/application/main.cpp 0 + + \section1 The Resource File + + As you will probably recall, for some of the actions, we + specified icons with file names starting with \c{:} and mentioned + that such file names aren't ordinary file names, but path in the + executable's stored resources. These resources are compiled + + The resources associated with an application are specified in a + \c .qrc file, an XML-based file format that lists files on the + disk. Here's the \c application.qrc file that's used by the + Application example: + + \quotefile mainwindows/application/application.qrc + + The \c .png files listed in the \c application.qrc file are files + that are part of the Application example's source tree. Paths are + relative to the directory where the \c application.qrc file is + located (the \c mainwindows/application directory). + + The resource file must be mentioned in the \c application.pro + file so that \c qmake knows about it: + + \snippet examples/mainwindows/application/application.pro 0 + + \c qmake will produce make rules to generate a file called \c + qrc_application.cpp that is linked into the application. This + file contains all the data for the images and other resources as + static C++ arrays of compressed binary data. See + \l{resources.html}{The Qt Resource System} for more information + about resources. +*/