doc/src/examples/icons.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 widgets/icons
       
    44     \title Icons Example
       
    45 
       
    46     The Icons example shows how QIcon can generate pixmaps reflecting
       
    47     an icon's state, mode and size. These pixmaps are generated from
       
    48     the set of pixmaps made available to the icon, and are used by Qt
       
    49     widgets to show an icon representing a particular action.
       
    50 
       
    51     \image icons-example.png Screenshot of the Icons example
       
    52 
       
    53     Contents:
       
    54 
       
    55     \tableofcontents
       
    56 
       
    57     \section1 QIcon Overview
       
    58 
       
    59     The QIcon class provides scalable icons in different modes and
       
    60     states. An icon's state and mode are depending on the intended use
       
    61     of the icon. Qt currently defines four modes:
       
    62 
       
    63     \table
       
    64     \header \o Mode \o Description
       
    65     \row
       
    66     \o QIcon::Normal
       
    67     \o Display the pixmap when the user is not interacting with the
       
    68        icon, but the functionality represented by the icon is
       
    69        available.
       
    70     \row
       
    71     \o QIcon::Active
       
    72     \o Display the pixmap when the functionality represented by the
       
    73        icon is available and the user is interacting with the icon,
       
    74        for example, moving the mouse over it or clicking it.
       
    75     \row
       
    76     \o QIcon::Disabled
       
    77     \o Display the pixmap when the functionality represented by
       
    78        the icon is not available.
       
    79     \row
       
    80     \o QIcon::Selected
       
    81     \o Display the pixmap when the icon is selected.
       
    82     \endtable
       
    83 
       
    84     QIcon's states are QIcon::On and QIcon::Off, which will display
       
    85     the pixmap when the widget is in the respective state. The most
       
    86     common usage of QIcon's states are when displaying checkable tool
       
    87     buttons or menu entries (see QAbstractButton::setCheckable() and
       
    88     QAction::setCheckable()). When a tool button or menu entry is
       
    89     checked, the QIcon's state is \l{QIcon::}{On}, otherwise it's
       
    90     \l{QIcon::}{Off}. You can, for example, use the QIcon's states to
       
    91     display differing pixmaps depending on whether the tool button or
       
    92     menu entry is checked or not.
       
    93 
       
    94     A QIcon can generate smaller, larger, active, disabled, and
       
    95     selected pixmaps from the set of pixmaps it is given. Such
       
    96     pixmaps are used by Qt widgets to show an icon representing a
       
    97     particular action.
       
    98 
       
    99     \section1 Overview of the Icons Application
       
   100 
       
   101     With the Icons application you get a preview of an icon's
       
   102     generated pixmaps reflecting its different states, modes and size.
       
   103 
       
   104     When an image is loaded into the application, it is converted into
       
   105     a pixmap and becomes a part of the set of pixmaps available to the
       
   106     icon. An image can be excluded from this set by checking off the
       
   107     related checkbox. The application provides a sub directory
       
   108     containing sets of images explicitly designed to illustrate how Qt
       
   109     renders an icon in different modes and states.
       
   110 
       
   111     The application allows you to manipulate the icon size with some
       
   112     predefined sizes and a spin box. The predefined sizes are style
       
   113     dependent, but most of the styles have the same values: Only the
       
   114     Macintosh style differ by using 32 pixels, instead of 16 pixels,
       
   115     for toolbar buttons. You can navigate between the available styles
       
   116     using the \gui View menu.
       
   117 
       
   118     \image icons-view-menu.png Screenshot of the View menu
       
   119 
       
   120     The \gui View menu also provide the option to make the application
       
   121     guess the icon state and mode from an image's file name. The \gui
       
   122     File menu provide the options of adding an image and removing all
       
   123     images. These last options are also available through a context
       
   124     menu that appears if you press the right mouse button within the
       
   125     table of image files. In addition, the \gui File menu provide an
       
   126     \gui Exit option, and the \gui Help menu provide information about
       
   127     the example and about Qt.
       
   128 
       
   129     \image icons_find_normal.png Screenshot of the Find Files
       
   130 
       
   131     The screenshot above shows the application with one image file
       
   132     loaded. The \gui {Guess Image Mode/State} is enabled and the
       
   133     style is Plastique.
       
   134 
       
   135     When QIcon is provided with only one available pixmap, that
       
   136     pixmap is used for all the states and modes. In this case the
       
   137     pixmap's icon mode is set to normal, and the generated pixmaps
       
   138     for the normal and active modes will look the same. But in
       
   139     disabled and selected mode, Qt will generate a slightly different
       
   140     pixmap.
       
   141 
       
   142     The next screenshot shows the application with an additional file
       
   143     loaded, providing QIcon with two available pixmaps. Note that the
       
   144     new image file's mode is set to disabled. When rendering the \gui
       
   145     Disabled mode pixmaps, Qt will now use the new image. We can see
       
   146     the difference: The generated disabled pixmap in the first
       
   147     screenshot is slightly darker than the pixmap with the originally
       
   148     set disabled mode in the second screenshot.
       
   149 
       
   150     \image icons_find_normal_disabled.png Screenshot of the Find Files
       
   151 
       
   152     When Qt renders the icon's pixmaps it searches through the set of
       
   153     available pixmaps following a particular algorithm. The algorithm
       
   154     is documented in QIcon, but we will describe some particular cases
       
   155     below.
       
   156 
       
   157     \image icons_monkey_active.png Screenshot of the Find Files
       
   158 
       
   159     In the screenshot above, we have set \c monkey_on_32x32 to be an
       
   160     Active/On pixmap and \c monkey_off_64x64 to be Normal/Off. To
       
   161     render the other six mode/state combinations, QIcon uses the
       
   162     search algorithm described in the table below:
       
   163 
       
   164     \table
       
   165     \header \o{2,1} Requested Pixmap \o{8,1} Preferred Alternatives (mode/state)
       
   166     \header \o Mode \o State \o 1  \o 2 \o 3 \o 4 \o 5 \o 6 \o 7 \o 8
       
   167     \row \o{1,2} Normal \o Off \o \bold N0 \o A0 \o N1 \o A1 \o D0 \o S0 \o D1 \o S1
       
   168     \row \o On \o N1 \o \bold A1 \o N0 \o A0 \o D1 \o S1 \o D0 \o S0
       
   169     \row \o{1,2} Active \o Off \o A0 \o \bold N0 \o A1 \o N1 \o D0 \o S0 \o D1 \o S1
       
   170     \row \o On \o \bold A1 \o N1 \o A0 \o N0 \o D1 \o S1 \o D0 \o S0
       
   171     \row \o{1,2} Disabled \o Off \o D0 \o \bold {N0'} \o A0' \o D1 \o N1' \o A1' \o S0' \o S1'
       
   172     \row \o On \o D1 \o N1' \o \bold {A1'} \o D0 \o N0' \o A0' \o S1' \o S0'
       
   173     \row \o{1,2} Selected \o Off \o S0 \o \bold {N0''} \o A0'' \o S1 \o N1'' \o A1'' \o D0'' \o D1''
       
   174     \row \o On \o S1 \o N1'' \o \bold {A1''} \o S0 \o N0'' \o A0'' \o D1'' \o D0''
       
   175     \endtable
       
   176 
       
   177     In the table, "0" and "1" stand for Off" and "On", respectively.
       
   178     Single quotes indicates that QIcon generates a disabled ("grayed
       
   179     out") version of the pixmap; similarly, double quuote indicate
       
   180     that QIcon generates a selected ("blued out") version of the
       
   181     pixmap.
       
   182 
       
   183     The alternatives used in the screenshot above are shown in bold.
       
   184     For example, the Disabled/Off pixmap is derived by graying out
       
   185     the Normal/Off pixmap (\c monkey_off_64x64).
       
   186 
       
   187     In the next screenshots, we loaded the whole set of monkey
       
   188     images. By checking or unchecking file names from the image list,
       
   189     we get different results:
       
   190 
       
   191     \table
       
   192     \row
       
   193     \o \inlineimage icons_monkey.png Screenshot of the Monkey Files
       
   194     \o \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files
       
   195     \endtable
       
   196 
       
   197     For any given mode/state combination, it is possible to specify
       
   198     several images at different resolutions. When rendering an
       
   199     icon, QIcon will automatically pick the most suitable image
       
   200     and scale it down if necessary. (QIcon never scales up images,
       
   201     because this rarely looks good.)
       
   202 
       
   203     The screenshots below shows what happens when we provide QIcon
       
   204     with three images (\c qt_extended_16x16.png, \c qt_extended_32x32.png, \c
       
   205     qt_extended_48x48.png) and try to render the QIcon at various
       
   206     resolutions:
       
   207 
       
   208     \table
       
   209     \row
       
   210     \o
       
   211     \o \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
       
   212     \o \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
       
   213     \o \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
       
   214     \row
       
   215     \o
       
   216     \o 8 x 8
       
   217     \o \bold {16 x 16}
       
   218     \o 17 x 17
       
   219     \row
       
   220     \o \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
       
   221     \o \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
       
   222     \o \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
       
   223     \o \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
       
   224     \row
       
   225     \o \bold {32 x 32}
       
   226     \o 33 x 33
       
   227     \o \bold {48 x 48}
       
   228     \o 64 x 64
       
   229     \endtable
       
   230 
       
   231     For sizes up to 16 x 16, QIcon uses \c qt_extended_16x16.png and
       
   232     scales it down if necessary. For sizes between 17 x 17 and 32 x
       
   233     32, it uses \c qt_extended_32x32.png. For sizes above 32 x 32, it uses
       
   234     \c qt_extended_48x48.png.
       
   235 
       
   236     \section1 Line-by-Line Walkthrough
       
   237 
       
   238     The Icons example consists of four classes:
       
   239 
       
   240     \list
       
   241     \o \c MainWindow inherits QMainWindow and is the main application
       
   242        window.
       
   243     \o \c IconPreviewArea is a custom widget that displays all
       
   244        combinations of states and modes for a given icon.
       
   245     \o \c IconSizeSpinBox is a subclass of QSpinBox that lets the
       
   246        user enter icon sizes (e.g., "48 x 48").
       
   247     \o \c ImageDelegate is a subclass of QItemDelegate that provides
       
   248        comboboxes for letting the user set the mode and state
       
   249        associated with an image.
       
   250     \endlist
       
   251 
       
   252     We will start by reviewing the \c IconPreviewArea class before we
       
   253     take a look at the \c MainWindow class. Finally, we will review the
       
   254     \c IconSizeSpinBox and \c ImageDelegate classes.
       
   255 
       
   256     \section2 IconPreviewArea Class Definition
       
   257 
       
   258     An \c IconPreviewArea widget consists of a group box containing a grid of
       
   259     QLabel widgets displaying headers and pixmaps.
       
   260 
       
   261     \image icons_preview_area.png Screenshot of IconPreviewArea.
       
   262 
       
   263     \snippet examples/widgets/icons/iconpreviewarea.h 0
       
   264 
       
   265     The \c IconPreviewArea class inherits QWidget. It displays the
       
   266     generated pixmaps corresponding to an icon's possible states and
       
   267     modes at a given size.
       
   268 
       
   269     We need two public functions to set the current icon and the
       
   270     icon's size. In addition the class has three private functions: We
       
   271     use the \c createHeaderLabel() and \c createPixmapLabel()
       
   272     functions when constructing the preview area, and we need the \c
       
   273     updatePixmapLabels() function to update the preview area when
       
   274     the icon or the icon's size has changed.
       
   275 
       
   276     The \c NumModes and \c NumStates constants reflect \l{QIcon}'s
       
   277     number of currently defined modes and states.
       
   278 
       
   279     \section2 IconPreviewArea Class Implementation
       
   280 
       
   281     \snippet examples/widgets/icons/iconpreviewarea.cpp 0
       
   282 
       
   283     In the constructor we create the labels displaying the headers and
       
   284     the icon's generated pixmaps, and add them to a grid layout.
       
   285 
       
   286     When creating the header labels, we make sure the enums \c
       
   287     NumModes and \c NumStates defined in the \c .h file, correspond
       
   288     with the number of labels that we create. Then if the enums at
       
   289     some point are changed, the \c Q_ASSERT() macro will alert that this
       
   290     part of the \c .cpp file needs to be updated as well.
       
   291 
       
   292     If the application is built in debug mode, the \c Q_ASSERT()
       
   293     macro will expand to
       
   294 
       
   295     \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 0
       
   296 
       
   297     In release mode, the macro simply disappear. The mode can be set
       
   298     in the application's \c .pro file. One way to do so is to add an
       
   299     option to \c qmake when building the application:
       
   300 
       
   301     \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 1
       
   302 
       
   303     or
       
   304 
       
   305     \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 2
       
   306 
       
   307     Another approach is to add this line directly to the \c .pro
       
   308     file.
       
   309 
       
   310     \snippet examples/widgets/icons/iconpreviewarea.cpp 1
       
   311     \codeline
       
   312     \snippet examples/widgets/icons/iconpreviewarea.cpp 2
       
   313 
       
   314     The public \c setIcon() and \c setSize() functions change the icon
       
   315     or the icon size, and make sure that the generated pixmaps are
       
   316     updated.
       
   317 
       
   318     \snippet examples/widgets/icons/iconpreviewarea.cpp 3
       
   319     \codeline
       
   320     \snippet examples/widgets/icons/iconpreviewarea.cpp 4
       
   321 
       
   322     We use the \c createHeaderLabel() and \c createPixmapLabel()
       
   323     functions to create the preview area's labels displaying the
       
   324     headers and the icon's generated pixmaps. Both functions return
       
   325     the QLabel that is created.
       
   326 
       
   327     \snippet examples/widgets/icons/iconpreviewarea.cpp 5
       
   328 
       
   329     We use the private \c updatePixmapLabel() function to update the
       
   330     generated pixmaps displayed in the preview area.
       
   331 
       
   332     For each mode, and for each state, we retrieve a pixmap using the
       
   333     QIcon::pixmap() function, which generates a pixmap corresponding
       
   334     to the given state, mode and size.
       
   335 
       
   336     \section2 MainWindow Class Definition
       
   337 
       
   338     The \c MainWindow widget consists of three main elements: an
       
   339     images group box, an icon size group box and a preview area.
       
   340 
       
   341     \image icons-example.png Screenshot of the Icons example
       
   342 
       
   343     \snippet examples/widgets/icons/mainwindow.h 0
       
   344 
       
   345     The MainWindow class inherits from QMainWindow. We reimplement the
       
   346     constructor, and declare several private slots:
       
   347 
       
   348     \list
       
   349     \o The \c about() slot simply provides information about the example.
       
   350     \o The \c changeStyle() slot changes the application's GUI style and
       
   351        adjust the style dependent size options.
       
   352     \o The \c changeSize() slot changes the size of the preview area's icon.
       
   353     \o The \c changeIcon() slot updates the set of pixmaps available to the
       
   354        icon displayed in the preview area.
       
   355     \o The \c addImage() slot allows the user to load a new image into the
       
   356        application.
       
   357     \endlist
       
   358 
       
   359     In addition we declare several private functions to simplify the
       
   360     constructor.
       
   361 
       
   362     \section2 MainWindow Class Implementation
       
   363 
       
   364     \snippet examples/widgets/icons/mainwindow.cpp 0
       
   365 
       
   366     In the constructor we first create the main window's central
       
   367     widget and its child widgets, and put them in a grid layout. Then
       
   368     we create the menus with their associated entries and actions.
       
   369 
       
   370     Before we resize the application window to a suitable size, we set
       
   371     the window title and determine the current style for the
       
   372     application. We also enable the icon size spin box by clicking the
       
   373     associated radio button, making the current value of the spin box
       
   374     the icon's initial size.
       
   375 
       
   376     \snippet examples/widgets/icons/mainwindow.cpp 1
       
   377 
       
   378     The \c about() slot displays a message box using the static
       
   379     QMessageBox::about() function. In this example it displays a
       
   380     simple box with information about the example.
       
   381 
       
   382     The \c about() function looks for a suitable icon in four
       
   383     locations: It prefers its parent's icon if that exists. If it
       
   384     doesn't, the function tries the top-level widget containing
       
   385     parent, and if that fails, it tries the active window. As a last
       
   386     resort it uses the QMessageBox's Information icon.
       
   387 
       
   388     \snippet examples/widgets/icons/mainwindow.cpp 2
       
   389 
       
   390     In the \c changeStyle() slot we first check the slot's
       
   391     parameter. If it is false we immediately return, otherwise we find
       
   392     out which style to change to, i.e. which action that triggered the
       
   393     slot, using the QObject::sender() function.
       
   394 
       
   395     This function returns the sender as a QObject pointer. Since we
       
   396     know that the sender is a QAction object, we can safely cast the
       
   397     QObject. We could have used a C-style cast or a C++ \c
       
   398     static_cast(), but as a defensive programming technique we use a
       
   399     \l qobject_cast(). The advantage is that if the object has the
       
   400     wrong type, a null pointer is returned. Crashes due to null
       
   401     pointers are much easier to diagnose than crashes due to unsafe
       
   402     casts.
       
   403 
       
   404     \snippet examples/widgets/icons/mainwindow.cpp 3
       
   405     \snippet examples/widgets/icons/mainwindow.cpp 4
       
   406 
       
   407     Once we have the action, we extract the style name using
       
   408     QAction::data(). Then we create a QStyle object using the static
       
   409     QStyleFactory::create() function.
       
   410 
       
   411     Although we can assume that the style is supported by the
       
   412     QStyleFactory: To be on the safe side, we use the \c Q_ASSERT()
       
   413     macro to check if the created style is valid before we use the
       
   414     QApplication::setStyle() function to set the application's GUI
       
   415     style to the new style. QApplication will automatically delete
       
   416     the style object when a new style is set or when the application
       
   417     exits.
       
   418 
       
   419     The predefined icon size options provided in the application are
       
   420     style dependent, so we need to update the labels in the icon size
       
   421     group box and in the end call the \c changeSize() slot to update
       
   422     the icon's size.
       
   423 
       
   424     \snippet examples/widgets/icons/mainwindow.cpp 5
       
   425 
       
   426     The \c changeSize() slot sets the size for the preview area's
       
   427     icon.
       
   428 
       
   429     To determine the new size we first check if the spin box is
       
   430     enabled. If it is, we extract the extent of the new size from the
       
   431     box. If it's not, we search through the predefined size options,
       
   432     extract the QStyle::PixelMetric and use the QStyle::pixelMetric()
       
   433     function to determine the extent. Then we create a QSize object
       
   434     based on the extent, and use that object to set the size of the
       
   435     preview area's icon.
       
   436 
       
   437     \snippet examples/widgets/icons/mainwindow.cpp 12
       
   438 
       
   439     The first thing we do when the \c addImage() slot is called, is to
       
   440     show a file dialog to the user. The easiest way to create a file
       
   441     dialog is to use QFileDialog's static functions. Here we use the
       
   442     \l {QFileDialog::getOpenFileNames()}{getOpenFileNames()} function
       
   443     that will return one or more existing files selected by the user.
       
   444 
       
   445     For each of the files the file dialog returns, we add a row to the
       
   446     table widget. The table widget is listing the images the user has
       
   447     loaded into the application.
       
   448 
       
   449     \snippet examples/widgets/icons/mainwindow.cpp 13
       
   450     \snippet examples/widgets/icons/mainwindow.cpp 14
       
   451 
       
   452     We retrieve the image name using the QFileInfo::baseName()
       
   453     function that returns the base name of the file without the path,
       
   454     and create the first table widget item in the row. Then we add the
       
   455     file's complete name to the item's data. Since an item can hold
       
   456     several information pieces, we need to assign the file name a role
       
   457     that will distinguish it from other data. This role can be Qt::UserRole
       
   458     or any value above it.
       
   459 
       
   460     We also make sure that the item is not editable by removing the
       
   461     Qt::ItemIsEditable flag. Table items are editable by default.
       
   462 
       
   463     \snippet examples/widgets/icons/mainwindow.cpp 15
       
   464     \snippet examples/widgets/icons/mainwindow.cpp 16
       
   465     \snippet examples/widgets/icons/mainwindow.cpp 17
       
   466 
       
   467     Then we create the second and third items in the row making the
       
   468     default mode Normal and the default state Off. But if the \gui
       
   469     {Guess Image Mode/State} option is checked, and the file name
       
   470     contains "_act", "_dis", or "_sel", the modes are changed to
       
   471     Active, Disabled, or Selected. And if the file name contains
       
   472     "_on", the state is changed to On. The sample files in the
       
   473     example's \c images subdirectory respect this naming convension.
       
   474 
       
   475     \snippet examples/widgets/icons/mainwindow.cpp 18
       
   476     \snippet examples/widgets/icons/mainwindow.cpp 19
       
   477 
       
   478     In the end we add the items to the associated row, and use the
       
   479     QTableWidget::openPersistentEditor() function to create
       
   480     comboboxes for the mode and state columns of the items.
       
   481 
       
   482     Due to the connection between the table widget's \l
       
   483     {QTableWidget::itemChanged()}{itemChanged()} signal and the \c
       
   484     changeIcon() slot, the new image is automatically converted into a
       
   485     pixmap and made part of the set of pixmaps available to the icon
       
   486     in the preview area. So, corresponding to this fact, we need to
       
   487     make sure that the new image's check box is enabled.
       
   488 
       
   489     \snippet examples/widgets/icons/mainwindow.cpp 6
       
   490     \snippet examples/widgets/icons/mainwindow.cpp 7
       
   491 
       
   492     The \c changeIcon() slot is called when the user alters the set
       
   493     of images listed in the QTableWidget, to update the QIcon object
       
   494     rendered by the \c IconPreviewArea.
       
   495 
       
   496     We first create a QIcon object, and then we run through the
       
   497     QTableWidget, which lists the images the user has loaded into the
       
   498     application.
       
   499 
       
   500     \snippet examples/widgets/icons/mainwindow.cpp 8
       
   501     \snippet examples/widgets/icons/mainwindow.cpp 9
       
   502     \snippet examples/widgets/icons/mainwindow.cpp 10
       
   503 
       
   504     We also extract the image file's name using the
       
   505     QTableWidgetItem::data() function. This function takes a
       
   506     Qt::DataItemRole as an argument to retrieve the right data
       
   507     (remember that an item can hold several pieces of information)
       
   508     and returns it as a QVariant. Then we use the
       
   509     QVariant::toString() function to get the file name as a QString.
       
   510 
       
   511     To create a pixmap from the file, we need to first create an
       
   512     image and then convert this image into a pixmap using
       
   513     QPixmap::fromImage(). Once we have the final pixmap, we add it,
       
   514     with its associated mode and state, to the QIcon's set of
       
   515     available pixmaps.
       
   516 
       
   517     \snippet examples/widgets/icons/mainwindow.cpp 11
       
   518 
       
   519     After running through the entire list of images, we change the
       
   520     icon of the preview area to the one we just created.
       
   521 
       
   522     \snippet examples/widgets/icons/mainwindow.cpp 20
       
   523 
       
   524     In the \c removeAllImages() slot, we simply set the table widget's
       
   525     row count to zero, automatically removing all the images the user
       
   526     has loaded into the application. Then we update the set of pixmaps
       
   527     available to the preview area's icon using the \c changeIcon()
       
   528     slot.
       
   529 
       
   530     \image icons_images_groupbox.png Screenshot of the images group box
       
   531 
       
   532     The \c createImagesGroupBox() function is implemented to simplify
       
   533     the constructor. The main purpose of the function is to create a
       
   534     QTableWidget that will keep track of the images the user has
       
   535     loaded into the application.
       
   536 
       
   537     \snippet examples/widgets/icons/mainwindow.cpp 21
       
   538 
       
   539     First we create a group box that will contain the table widget.
       
   540     Then we create a QTableWidget and customize it to suit our
       
   541     purposes.
       
   542 
       
   543     We call QAbstractItemView::setSelectionMode() to prevent the user
       
   544     from selecting items.
       
   545 
       
   546     The QAbstractItemView::setItemDelegate() call sets the item
       
   547     delegate for the table widget. We create a \c ImageDelegate that
       
   548     we make the item delegate for our view.
       
   549 
       
   550     The QItemDelegate class can be used to provide an editor for an item view
       
   551     class that is subclassed from QAbstractItemView. Using a delegate
       
   552     for this purpose allows the editing mechanism to be customized and
       
   553     developed independently from the model and view.
       
   554 
       
   555     In this example we derive \c ImageDelegate from QItemDelegate.
       
   556     QItemDelegate usually provides line editors, while our subclass
       
   557     \c ImageDelegate, provides comboboxes for the mode and state
       
   558     fields.
       
   559 
       
   560     \snippet examples/widgets/icons/mainwindow.cpp 22
       
   561     \snippet examples/widgets/icons/mainwindow.cpp 23
       
   562 
       
   563     Then we customize the QTableWidget's horizontal header, and hide
       
   564     the vertical header.
       
   565 
       
   566     \snippet examples/widgets/icons/mainwindow.cpp 24
       
   567     \snippet examples/widgets/icons/mainwindow.cpp 25
       
   568 
       
   569     At the end, we connect the QTableWidget::itemChanged() signal to
       
   570     the \c changeIcon() slot to ensuret that the preview area is in
       
   571     sync with the image table.
       
   572 
       
   573     \image icons_size_groupbox.png Screenshot of the icon size group box
       
   574 
       
   575     The \c createIconSizeGroupBox() function is called from the
       
   576     constructor. It creates the widgets controlling the size of the
       
   577     preview area's icon.
       
   578 
       
   579     \snippet examples/widgets/icons/mainwindow.cpp 26
       
   580 
       
   581     First we create a group box that will contain all the widgets;
       
   582     then we create the radio buttons and the spin box.
       
   583 
       
   584     The spin box is not a regular QSpinBox but an \c IconSizeSpinBox.
       
   585     The \c IconSizeSpinBox class inherits QSpinBox and reimplements
       
   586     two functions: QSpinBox::textFromValue() and
       
   587     QSpinBox::valueFromText(). The \c IconSizeSpinBox is designed to
       
   588     handle icon sizes, e.g., "32 x 32", instead of plain integer
       
   589     values.
       
   590 
       
   591     \snippet examples/widgets/icons/mainwindow.cpp 27
       
   592 
       
   593     Then we connect all of the radio buttons
       
   594     \l{QRadioButton::toggled()}{toggled()} signals and the spin box's
       
   595     \l {QSpinBox::valueChanged()}{valueChanged()} signal to the \c
       
   596     changeSize() slot to make sure that the size of the preview
       
   597     area's icon is updated whenever the user changes the icon size.
       
   598     In the end we put the widgets in a layout that we install on the
       
   599     group box.
       
   600 
       
   601     \snippet examples/widgets/icons/mainwindow.cpp 28
       
   602 
       
   603     In the \c createActions() function we create and customize all the
       
   604     actions needed to implement the functionality associated with the
       
   605     menu entries in the application.
       
   606 
       
   607     In particular we create the \c styleActionGroup based on the
       
   608     currently available GUI styles using
       
   609     QStyleFactory. QStyleFactory::keys() returns a list of valid keys,
       
   610     typically including "windows", "motif", "cde", and
       
   611     "plastique". Depending on the platform, "windowsxp" and
       
   612     "macintosh" may be available.
       
   613 
       
   614     We create one action for each key, and adds the action to the
       
   615     action group. Also, for each action, we call QAction::setData()
       
   616     with the style name. We will retrieve it later using
       
   617     QAction::data().
       
   618 
       
   619     \snippet examples/widgets/icons/mainwindow.cpp 29
       
   620 
       
   621     In the \c createMenu() function, we add the previously created
       
   622     actions to the \gui File, \gui View and \gui Help menus.
       
   623 
       
   624     The QMenu class provides a menu widget for use in menu bars,
       
   625     context menus, and other popup menus. We put each menu in the
       
   626     application's menu bar, which we retrieve using
       
   627     QMainWindow::menuBar().
       
   628 
       
   629     \snippet examples/widgets/icons/mainwindow.cpp 30
       
   630 
       
   631     QWidgets have a \l{QWidget::contextMenuPolicy}{contextMenuPolicy}
       
   632     property that controls how the widget should behave when the user
       
   633     requests a context menu (e.g., by right-clicking). We set the
       
   634     QTableWidget's context menu policy to Qt::ActionsContextMenu,
       
   635     meaning that the \l{QAction}s associated with the widget should
       
   636     appear in its context menu.
       
   637 
       
   638     Then we add the \gui{Add Image} and \gui{Remove All Images}
       
   639     actions to the table widget. They will then appear in the table
       
   640     widget's context menu.
       
   641 
       
   642     \snippet examples/widgets/icons/mainwindow.cpp 31
       
   643 
       
   644     In the \c checkCurrentStyle() function we go through the group of
       
   645     style actions, looking for the current GUI style.
       
   646 
       
   647     For each action, we first extract the style name using
       
   648     QAction::data(). Since this is only a QStyleFactory key (e.g.,
       
   649     "macintosh"), we cannot compare it directly to the current
       
   650     style's class name. We need to create a QStyle object using the
       
   651     static QStyleFactory::create() function and compare the class
       
   652     name of the created QStyle object with that of the current style.
       
   653     As soon as we are done with a QStyle candidate, we delete it.
       
   654 
       
   655     For all QObject subclasses that use the \c Q_OBJECT macro, the
       
   656     class name of an object is available through its
       
   657     \l{QObject::metaObject()}{meta-object}.
       
   658 
       
   659     We can assume that the style is supported by
       
   660     QStyleFactory, but to be on the safe side we use the \c
       
   661     Q_ASSERT() macro to make sure that QStyleFactory::create()
       
   662     returned a valid pointer.
       
   663 
       
   664     \section2 IconSizeSpinBox Class Definition
       
   665 
       
   666     \snippet examples/widgets/icons/iconsizespinbox.h 0
       
   667 
       
   668     The \c IconSizeSpinBox class is a subclass of QSpinBox. A plain
       
   669     QSpinBox can only handle integers. But since we want to display
       
   670     the spin box's values in a more sophisticated way, we need to
       
   671     subclass QSpinBox and reimplement the QSpinBox::textFromValue()
       
   672     and QSpinBox::valueFromText() functions.
       
   673 
       
   674     \image icons_size_spinbox.png Screenshot of the icon size spinbox
       
   675 
       
   676     \section2 IconSizeSpinBox Class Implementation
       
   677 
       
   678     \snippet examples/widgets/icons/iconsizespinbox.cpp 0
       
   679 
       
   680     The constructor is trivial.
       
   681 
       
   682     \snippet examples/widgets/icons/iconsizespinbox.cpp 2
       
   683 
       
   684     QSpinBox::textFromValue() is used by the spin box whenever it
       
   685     needs to display a value. The default implementation returns a
       
   686     base 10 representation of the \c value parameter.
       
   687 
       
   688     Our reimplementation returns a QString of the form "32 x 32".
       
   689 
       
   690     \snippet examples/widgets/icons/iconsizespinbox.cpp 1
       
   691 
       
   692     The QSpinBox::valueFromText() function is used by the spin box
       
   693     whenever it needs to interpret text typed in by the user. Since
       
   694     we reimplement the \c textFromValue() function we also need to
       
   695     reimplement the \c valueFromText() function to interpret the
       
   696     parameter text and return the associated int value.
       
   697 
       
   698     We parse the text using a regular expression (a QRegExp). We
       
   699     define an expression that matches one or several digits,
       
   700     optionally followed by whitespace, an "x" or the times symbol,
       
   701     whitespace and one or several digits again.
       
   702 
       
   703     The first digits of the regular expression are captured using
       
   704     parentheses. This enables us to use the QRegExp::cap() or
       
   705     QRegExp::capturedTexts() functions to extract the matched
       
   706     characters. If the first and second numbers of the spin box value
       
   707     differ (e.g., "16 x 24"), we use the first number.
       
   708 
       
   709     When the user presses \key Enter, QSpinBox first calls
       
   710     QSpinBox::valueFromText() to interpret the text typed by the
       
   711     user, then QSpinBox::textFromValue() to present it in a canonical
       
   712     format (e.g., "16 x 16").
       
   713 
       
   714     \section2 ImageDelegate Class Definition
       
   715 
       
   716     \snippet examples/widgets/icons/imagedelegate.h 0
       
   717 
       
   718     The \c ImageDelegate class is a subclass of QItemDelegate. The
       
   719     QItemDelegate class provides display and editing facilities for
       
   720     data items from a model. A single QItemDelegate object is
       
   721     responsible for all items displayed in a item view (in our case,
       
   722     a QTableWidget).
       
   723 
       
   724     A QItemDelegate can be used to provide an editor for an item view
       
   725     class that is subclassed from QAbstractItemView. Using a delegate
       
   726     for this purpose allows the editing mechanism to be customized and
       
   727     developed independently from the model and view.
       
   728 
       
   729     \snippet examples/widgets/icons/imagedelegate.h 1
       
   730 
       
   731     The default implementation of QItemDelegate creates a QLineEdit.
       
   732     Since we want the editor to be a QComboBox, we need to subclass
       
   733     QItemDelegate and reimplement the QItemDelegate::createEditor(),
       
   734     QItemDelegate::setEditorData() and QItemDelegate::setModelData()
       
   735     functions.
       
   736 
       
   737     \snippet examples/widgets/icons/imagedelegate.h 2
       
   738 
       
   739     The \c emitCommitData() slot is used to emit the
       
   740     QImageDelegate::commitData() signal with the appropriate
       
   741     argument.
       
   742 
       
   743     \section2 ImageDelegate Class Implementation
       
   744 
       
   745     \snippet examples/widgets/icons/imagedelegate.cpp 0
       
   746 
       
   747     The constructor is trivial.
       
   748 
       
   749     \snippet examples/widgets/icons/imagedelegate.cpp 1
       
   750 
       
   751     The default QItemDelegate::createEditor() implementation returns
       
   752     the widget used to edit the item specified by the model and item
       
   753     index for editing. The parent widget and style option are used to
       
   754     control the appearance of the editor widget.
       
   755 
       
   756     Our reimplementation create and populate a combobox instead of
       
   757     the default line edit. The contents of the combobox depends on
       
   758     the column in the table for which the editor is requested. Column
       
   759     1 contains the QIcon modes, whereas column 2 contains the QIcon
       
   760     states.
       
   761 
       
   762     In addition, we connect the combobox's \l
       
   763     {QComboBox::activated()}{activated()} signal to the \c
       
   764     emitCommitData() slot to emit the
       
   765     QAbstractItemDelegate::commitData() signal whenever the user
       
   766     chooses an item using the combobox. This ensures that the rest of
       
   767     the application notices the change and updates itself.
       
   768 
       
   769     \snippet examples/widgets/icons/imagedelegate.cpp 2
       
   770 
       
   771     The QItemDelegate::setEditorData() function is used by
       
   772     QTableWidget to transfer data from a QTableWidgetItem to the
       
   773     editor. The data is stored as a string; we use
       
   774     QComboBox::findText() to locate it in the combobox.
       
   775 
       
   776     Delegates work in terms of models, not items. This makes it
       
   777     possible to use them with any item view class (e.g., QListView,
       
   778     QListWidget, QTreeView, etc.). The transition between model and
       
   779     items is done implicitly by QTableWidget; we don't need to worry
       
   780     about it.
       
   781 
       
   782     \snippet examples/widgets/icons/imagedelegate.cpp 3
       
   783 
       
   784     The QItemDelegate::setEditorData() function is used by QTableWidget
       
   785     to transfer data back from the editor to the \l{QTableWidgetItem}.
       
   786 
       
   787     \snippet examples/widgets/icons/imagedelegate.cpp 4
       
   788 
       
   789     The \c emitCommitData() slot simply emit the
       
   790     QAbstractItemDelegate::commitData() signal for the editor that
       
   791     triggered the slot. This signal must be emitted when the editor
       
   792     widget has completed editing the data, and wants to write it back
       
   793     into the model.
       
   794 */