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