doc/src/examples/application.qdoc
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 */