source: trunk/doc/src/examples/icons.qdoc

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 32.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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:FDL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in a
14** written agreement between you and Nokia.
15**
16** GNU Free Documentation License
17** Alternatively, this file may be used under the terms of the GNU Free
18** Documentation License version 1.3 as published by the Free Software
19** Foundation and appearing in the file included in the packaging of this
20** file.
21**
22** If you have questions regarding the use of this file, please contact
23** Nokia at qt-info@nokia.com.
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 \o Mode \o Description
51 \row
52 \o QIcon::Normal
53 \o 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 \o QIcon::Active
58 \o 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 \o QIcon::Disabled
63 \o Display the pixmap when the functionality represented by
64 the icon is not available.
65 \row
66 \o QIcon::Selected
67 \o 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 \gui View menu.
103
104 \image icons-view-menu.png Screenshot of the View menu
105
106 The \gui View menu also provide the option to make the application
107 guess the icon state and mode from an image's file name. The \gui
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 \gui File menu provide an
112 \gui Exit option, and the \gui 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 \gui {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 \gui
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
151 \header \o{2,1} Requested Pixmap \o{8,1} Preferred Alternatives (mode/state)
152 \header \o Mode \o State \o 1 \o 2 \o 3 \o 4 \o 5 \o 6 \o 7 \o 8
153 \row \o{1,2} Normal \o Off \o \bold N0 \o A0 \o N1 \o A1 \o D0 \o S0 \o D1 \o S1
154 \row \o On \o N1 \o \bold A1 \o N0 \o A0 \o D1 \o S1 \o D0 \o S0
155 \row \o{1,2} Active \o Off \o A0 \o \bold N0 \o A1 \o N1 \o D0 \o S0 \o D1 \o S1
156 \row \o On \o \bold A1 \o N1 \o A0 \o N0 \o D1 \o S1 \o D0 \o S0
157 \row \o{1,2} Disabled \o Off \o D0 \o \bold {N0'} \o A0' \o D1 \o N1' \o A1' \o S0' \o S1'
158 \row \o On \o D1 \o N1' \o \bold {A1'} \o D0 \o N0' \o A0' \o S1' \o S0'
159 \row \o{1,2} Selected \o Off \o S0 \o \bold {N0''} \o A0'' \o S1 \o N1'' \o A1'' \o D0'' \o D1''
160 \row \o On \o S1 \o N1'' \o \bold {A1''} \o S0 \o N0'' \o A0'' \o D1'' \o 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 \o \inlineimage icons_monkey.png Screenshot of the Monkey Files
180 \o \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 \o
197 \o \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
198 \o \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
199 \o \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
200 \row
201 \o
202 \o 8 x 8
203 \o \bold {16 x 16}
204 \o 17 x 17
205 \row
206 \o \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
207 \o \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
208 \o \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
209 \o \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
210 \row
211 \o \bold {32 x 32}
212 \o 33 x 33
213 \o \bold {48 x 48}
214 \o 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 \o \c MainWindow inherits QMainWindow and is the main application
228 window.
229 \o \c IconPreviewArea is a custom widget that displays all
230 combinations of states and modes for a given icon.
231 \o \c IconSizeSpinBox is a subclass of QSpinBox that lets the
232 user enter icon sizes (e.g., "48 x 48").
233 \o \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 examples/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 examples/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 \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 0
282
283 In release mode, the macro simply disappear. The mode can be set
284 in the application's \c .pro file. One way to do so is to add an
285 option to \c qmake when building the application:
286
287 \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 1
288
289 or
290
291 \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 2
292
293 Another approach is to add this line directly to the \c .pro
294 file.
295
296 \snippet examples/widgets/icons/iconpreviewarea.cpp 1
297 \codeline
298 \snippet examples/widgets/icons/iconpreviewarea.cpp 2
299
300 The public \c setIcon() and \c setSize() functions change the icon
301 or the icon size, and make sure that the generated pixmaps are
302 updated.
303
304 \snippet examples/widgets/icons/iconpreviewarea.cpp 3
305 \codeline
306 \snippet examples/widgets/icons/iconpreviewarea.cpp 4
307
308 We use the \c createHeaderLabel() and \c createPixmapLabel()
309 functions to create the preview area's labels displaying the
310 headers and the icon's generated pixmaps. Both functions return
311 the QLabel that is created.
312
313 \snippet examples/widgets/icons/iconpreviewarea.cpp 5
314
315 We use the private \c updatePixmapLabel() function to update the
316 generated pixmaps displayed in the preview area.
317
318 For each mode, and for each state, we retrieve a pixmap using the
319 QIcon::pixmap() function, which generates a pixmap corresponding
320 to the given state, mode and size.
321
322 \section2 MainWindow Class Definition
323
324 The \c MainWindow widget consists of three main elements: an
325 images group box, an icon size group box and a preview area.
326
327 \image icons-example.png Screenshot of the Icons example
328
329 \snippet examples/widgets/icons/mainwindow.h 0
330
331 The MainWindow class inherits from QMainWindow. We reimplement the
332 constructor, and declare several private slots:
333
334 \list
335 \o The \c about() slot simply provides information about the example.
336 \o The \c changeStyle() slot changes the application's GUI style and
337 adjust the style dependent size options.
338 \o The \c changeSize() slot changes the size of the preview area's icon.
339 \o The \c changeIcon() slot updates the set of pixmaps available to the
340 icon displayed in the preview area.
341 \o The \c addImage() slot allows the user to load a new image into the
342 application.
343 \endlist
344
345 In addition we declare several private functions to simplify the
346 constructor.
347
348 \section2 MainWindow Class Implementation
349
350 \snippet examples/widgets/icons/mainwindow.cpp 0
351
352 In the constructor we first create the main window's central
353 widget and its child widgets, and put them in a grid layout. Then
354 we create the menus with their associated entries and actions.
355
356 Before we resize the application window to a suitable size, we set
357 the window title and determine the current style for the
358 application. We also enable the icon size spin box by clicking the
359 associated radio button, making the current value of the spin box
360 the icon's initial size.
361
362 \snippet examples/widgets/icons/mainwindow.cpp 1
363
364 The \c about() slot displays a message box using the static
365 QMessageBox::about() function. In this example it displays a
366 simple box with information about the example.
367
368 The \c about() function looks for a suitable icon in four
369 locations: It prefers its parent's icon if that exists. If it
370 doesn't, the function tries the top-level widget containing
371 parent, and if that fails, it tries the active window. As a last
372 resort it uses the QMessageBox's Information icon.
373
374 \snippet examples/widgets/icons/mainwindow.cpp 2
375
376 In the \c changeStyle() slot we first check the slot's
377 parameter. If it is false we immediately return, otherwise we find
378 out which style to change to, i.e. which action that triggered the
379 slot, using the QObject::sender() function.
380
381 This function returns the sender as a QObject pointer. Since we
382 know that the sender is a QAction object, we can safely cast the
383 QObject. We could have used a C-style cast or a C++ \c
384 static_cast(), but as a defensive programming technique we use a
385 \l qobject_cast(). The advantage is that if the object has the
386 wrong type, a null pointer is returned. Crashes due to null
387 pointers are much easier to diagnose than crashes due to unsafe
388 casts.
389
390 \snippet examples/widgets/icons/mainwindow.cpp 3
391 \snippet examples/widgets/icons/mainwindow.cpp 4
392
393 Once we have the action, we extract the style name using
394 QAction::data(). Then we create a QStyle object using the static
395 QStyleFactory::create() function.
396
397 Although we can assume that the style is supported by the
398 QStyleFactory: To be on the safe side, we use the \c Q_ASSERT()
399 macro to check if the created style is valid before we use the
400 QApplication::setStyle() function to set the application's GUI
401 style to the new style. QApplication will automatically delete
402 the style object when a new style is set or when the application
403 exits.
404
405 The predefined icon size options provided in the application are
406 style dependent, so we need to update the labels in the icon size
407 group box and in the end call the \c changeSize() slot to update
408 the icon's size.
409
410 \snippet examples/widgets/icons/mainwindow.cpp 5
411
412 The \c changeSize() slot sets the size for the preview area's
413 icon.
414
415 To determine the new size we first check if the spin box is
416 enabled. If it is, we extract the extent of the new size from the
417 box. If it's not, we search through the predefined size options,
418 extract the QStyle::PixelMetric and use the QStyle::pixelMetric()
419 function to determine the extent. Then we create a QSize object
420 based on the extent, and use that object to set the size of the
421 preview area's icon.
422
423 \snippet examples/widgets/icons/mainwindow.cpp 12
424
425 The first thing we do when the \c addImage() slot is called, is to
426 show a file dialog to the user. The easiest way to create a file
427 dialog is to use QFileDialog's static functions. Here we use the
428 \l {QFileDialog::getOpenFileNames()}{getOpenFileNames()} function
429 that will return one or more existing files selected by the user.
430
431 For each of the files the file dialog returns, we add a row to the
432 table widget. The table widget is listing the images the user has
433 loaded into the application.
434
435 \snippet examples/widgets/icons/mainwindow.cpp 13
436 \snippet examples/widgets/icons/mainwindow.cpp 14
437
438 We retrieve the image name using the QFileInfo::baseName()
439 function that returns the base name of the file without the path,
440 and create the first table widget item in the row. Then we add the
441 file's complete name to the item's data. Since an item can hold
442 several information pieces, we need to assign the file name a role
443 that will distinguish it from other data. This role can be Qt::UserRole
444 or any value above it.
445
446 We also make sure that the item is not editable by removing the
447 Qt::ItemIsEditable flag. Table items are editable by default.
448
449 \snippet examples/widgets/icons/mainwindow.cpp 15
450 \snippet examples/widgets/icons/mainwindow.cpp 16
451 \snippet examples/widgets/icons/mainwindow.cpp 17
452
453 Then we create the second and third items in the row making the
454 default mode Normal and the default state Off. But if the \gui
455 {Guess Image Mode/State} option is checked, and the file name
456 contains "_act", "_dis", or "_sel", the modes are changed to
457 Active, Disabled, or Selected. And if the file name contains
458 "_on", the state is changed to On. The sample files in the
459 example's \c images subdirectory respect this naming convension.
460
461 \snippet examples/widgets/icons/mainwindow.cpp 18
462 \snippet examples/widgets/icons/mainwindow.cpp 19
463
464 In the end we add the items to the associated row, and use the
465 QTableWidget::openPersistentEditor() function to create
466 comboboxes for the mode and state columns of the items.
467
468 Due to the connection between the table widget's \l
469 {QTableWidget::itemChanged()}{itemChanged()} signal and the \c
470 changeIcon() slot, the new image is automatically converted into a
471 pixmap and made part of the set of pixmaps available to the icon
472 in the preview area. So, corresponding to this fact, we need to
473 make sure that the new image's check box is enabled.
474
475 \snippet examples/widgets/icons/mainwindow.cpp 6
476 \snippet examples/widgets/icons/mainwindow.cpp 7
477
478 The \c changeIcon() slot is called when the user alters the set
479 of images listed in the QTableWidget, to update the QIcon object
480 rendered by the \c IconPreviewArea.
481
482 We first create a QIcon object, and then we run through the
483 QTableWidget, which lists the images the user has loaded into the
484 application.
485
486 \snippet examples/widgets/icons/mainwindow.cpp 8
487 \snippet examples/widgets/icons/mainwindow.cpp 9
488 \snippet examples/widgets/icons/mainwindow.cpp 10
489
490 We also extract the image file's name using the
491 QTableWidgetItem::data() function. This function takes a
492 Qt::DataItemRole as an argument to retrieve the right data
493 (remember that an item can hold several pieces of information)
494 and returns it as a QVariant. Then we use the
495 QVariant::toString() function to get the file name as a QString.
496
497 To create a pixmap from the file, we need to first create an
498 image and then convert this image into a pixmap using
499 QPixmap::fromImage(). Once we have the final pixmap, we add it,
500 with its associated mode and state, to the QIcon's set of
501 available pixmaps.
502
503 \snippet examples/widgets/icons/mainwindow.cpp 11
504
505 After running through the entire list of images, we change the
506 icon of the preview area to the one we just created.
507
508 \snippet examples/widgets/icons/mainwindow.cpp 20
509
510 In the \c removeAllImages() slot, we simply set the table widget's
511 row count to zero, automatically removing all the images the user
512 has loaded into the application. Then we update the set of pixmaps
513 available to the preview area's icon using the \c changeIcon()
514 slot.
515
516 \image icons_images_groupbox.png Screenshot of the images group box
517
518 The \c createImagesGroupBox() function is implemented to simplify
519 the constructor. The main purpose of the function is to create a
520 QTableWidget that will keep track of the images the user has
521 loaded into the application.
522
523 \snippet examples/widgets/icons/mainwindow.cpp 21
524
525 First we create a group box that will contain the table widget.
526 Then we create a QTableWidget and customize it to suit our
527 purposes.
528
529 We call QAbstractItemView::setSelectionMode() to prevent the user
530 from selecting items.
531
532 The QAbstractItemView::setItemDelegate() call sets the item
533 delegate for the table widget. We create a \c ImageDelegate that
534 we make the item delegate for our view.
535
536 The QItemDelegate class can be used to provide an editor for an item view
537 class that is subclassed from QAbstractItemView. Using a delegate
538 for this purpose allows the editing mechanism to be customized and
539 developed independently from the model and view.
540
541 In this example we derive \c ImageDelegate from QItemDelegate.
542 QItemDelegate usually provides line editors, while our subclass
543 \c ImageDelegate, provides comboboxes for the mode and state
544 fields.
545
546 \snippet examples/widgets/icons/mainwindow.cpp 22
547 \snippet examples/widgets/icons/mainwindow.cpp 23
548
549 Then we customize the QTableWidget's horizontal header, and hide
550 the vertical header.
551
552 \snippet examples/widgets/icons/mainwindow.cpp 24
553 \snippet examples/widgets/icons/mainwindow.cpp 25
554
555 At the end, we connect the QTableWidget::itemChanged() signal to
556 the \c changeIcon() slot to ensuret that the preview area is in
557 sync with the image table.
558
559 \image icons_size_groupbox.png Screenshot of the icon size group box
560
561 The \c createIconSizeGroupBox() function is called from the
562 constructor. It creates the widgets controlling the size of the
563 preview area's icon.
564
565 \snippet examples/widgets/icons/mainwindow.cpp 26
566
567 First we create a group box that will contain all the widgets;
568 then we create the radio buttons and the spin box.
569
570 The spin box is not a regular QSpinBox but an \c IconSizeSpinBox.
571 The \c IconSizeSpinBox class inherits QSpinBox and reimplements
572 two functions: QSpinBox::textFromValue() and
573 QSpinBox::valueFromText(). The \c IconSizeSpinBox is designed to
574 handle icon sizes, e.g., "32 x 32", instead of plain integer
575 values.
576
577 \snippet examples/widgets/icons/mainwindow.cpp 27
578
579 Then we connect all of the radio buttons
580 \l{QRadioButton::toggled()}{toggled()} signals and the spin box's
581 \l {QSpinBox::valueChanged()}{valueChanged()} signal to the \c
582 changeSize() slot to make sure that the size of the preview
583 area's icon is updated whenever the user changes the icon size.
584 In the end we put the widgets in a layout that we install on the
585 group box.
586
587 \snippet examples/widgets/icons/mainwindow.cpp 28
588
589 In the \c createActions() function we create and customize all the
590 actions needed to implement the functionality associated with the
591 menu entries in the application.
592
593 In particular we create the \c styleActionGroup based on the
594 currently available GUI styles using
595 QStyleFactory. QStyleFactory::keys() returns a list of valid keys,
596 typically including "windows", "motif", "cde", and
597 "plastique". Depending on the platform, "windowsxp" and
598 "macintosh" may be available.
599
600 We create one action for each key, and adds the action to the
601 action group. Also, for each action, we call QAction::setData()
602 with the style name. We will retrieve it later using
603 QAction::data().
604
605 \snippet examples/widgets/icons/mainwindow.cpp 29
606
607 In the \c createMenu() function, we add the previously created
608 actions to the \gui File, \gui View and \gui Help menus.
609
610 The QMenu class provides a menu widget for use in menu bars,
611 context menus, and other popup menus. We put each menu in the
612 application's menu bar, which we retrieve using
613 QMainWindow::menuBar().
614
615 \snippet examples/widgets/icons/mainwindow.cpp 30
616
617 QWidgets have a \l{QWidget::contextMenuPolicy}{contextMenuPolicy}
618 property that controls how the widget should behave when the user
619 requests a context menu (e.g., by right-clicking). We set the
620 QTableWidget's context menu policy to Qt::ActionsContextMenu,
621 meaning that the \l{QAction}s associated with the widget should
622 appear in its context menu.
623
624 Then we add the \gui{Add Image} and \gui{Remove All Images}
625 actions to the table widget. They will then appear in the table
626 widget's context menu.
627
628 \snippet examples/widgets/icons/mainwindow.cpp 31
629
630 In the \c checkCurrentStyle() function we go through the group of
631 style actions, looking for the current GUI style.
632
633 For each action, we first extract the style name using
634 QAction::data(). Since this is only a QStyleFactory key (e.g.,
635 "macintosh"), we cannot compare it directly to the current
636 style's class name. We need to create a QStyle object using the
637 static QStyleFactory::create() function and compare the class
638 name of the created QStyle object with that of the current style.
639 As soon as we are done with a QStyle candidate, we delete it.
640
641 For all QObject subclasses that use the \c Q_OBJECT macro, the
642 class name of an object is available through its
643 \l{QObject::metaObject()}{meta-object}.
644
645 We can assume that the style is supported by
646 QStyleFactory, but to be on the safe side we use the \c
647 Q_ASSERT() macro to make sure that QStyleFactory::create()
648 returned a valid pointer.
649
650 \section2 IconSizeSpinBox Class Definition
651
652 \snippet examples/widgets/icons/iconsizespinbox.h 0
653
654 The \c IconSizeSpinBox class is a subclass of QSpinBox. A plain
655 QSpinBox can only handle integers. But since we want to display
656 the spin box's values in a more sophisticated way, we need to
657 subclass QSpinBox and reimplement the QSpinBox::textFromValue()
658 and QSpinBox::valueFromText() functions.
659
660 \image icons_size_spinbox.png Screenshot of the icon size spinbox
661
662 \section2 IconSizeSpinBox Class Implementation
663
664 \snippet examples/widgets/icons/iconsizespinbox.cpp 0
665
666 The constructor is trivial.
667
668 \snippet examples/widgets/icons/iconsizespinbox.cpp 2
669
670 QSpinBox::textFromValue() is used by the spin box whenever it
671 needs to display a value. The default implementation returns a
672 base 10 representation of the \c value parameter.
673
674 Our reimplementation returns a QString of the form "32 x 32".
675
676 \snippet examples/widgets/icons/iconsizespinbox.cpp 1
677
678 The QSpinBox::valueFromText() function is used by the spin box
679 whenever it needs to interpret text typed in by the user. Since
680 we reimplement the \c textFromValue() function we also need to
681 reimplement the \c valueFromText() function to interpret the
682 parameter text and return the associated int value.
683
684 We parse the text using a regular expression (a QRegExp). We
685 define an expression that matches one or several digits,
686 optionally followed by whitespace, an "x" or the times symbol,
687 whitespace and one or several digits again.
688
689 The first digits of the regular expression are captured using
690 parentheses. This enables us to use the QRegExp::cap() or
691 QRegExp::capturedTexts() functions to extract the matched
692 characters. If the first and second numbers of the spin box value
693 differ (e.g., "16 x 24"), we use the first number.
694
695 When the user presses \key Enter, QSpinBox first calls
696 QSpinBox::valueFromText() to interpret the text typed by the
697 user, then QSpinBox::textFromValue() to present it in a canonical
698 format (e.g., "16 x 16").
699
700 \section2 ImageDelegate Class Definition
701
702 \snippet examples/widgets/icons/imagedelegate.h 0
703
704 The \c ImageDelegate class is a subclass of QItemDelegate. The
705 QItemDelegate class provides display and editing facilities for
706 data items from a model. A single QItemDelegate object is
707 responsible for all items displayed in a item view (in our case,
708 a QTableWidget).
709
710 A QItemDelegate can be used to provide an editor for an item view
711 class that is subclassed from QAbstractItemView. Using a delegate
712 for this purpose allows the editing mechanism to be customized and
713 developed independently from the model and view.
714
715 \snippet examples/widgets/icons/imagedelegate.h 1
716
717 The default implementation of QItemDelegate creates a QLineEdit.
718 Since we want the editor to be a QComboBox, we need to subclass
719 QItemDelegate and reimplement the QItemDelegate::createEditor(),
720 QItemDelegate::setEditorData() and QItemDelegate::setModelData()
721 functions.
722
723 \snippet examples/widgets/icons/imagedelegate.h 2
724
725 The \c emitCommitData() slot is used to emit the
726 QImageDelegate::commitData() signal with the appropriate
727 argument.
728
729 \section2 ImageDelegate Class Implementation
730
731 \snippet examples/widgets/icons/imagedelegate.cpp 0
732
733 The constructor is trivial.
734
735 \snippet examples/widgets/icons/imagedelegate.cpp 1
736
737 The default QItemDelegate::createEditor() implementation returns
738 the widget used to edit the item specified by the model and item
739 index for editing. The parent widget and style option are used to
740 control the appearance of the editor widget.
741
742 Our reimplementation create and populate a combobox instead of
743 the default line edit. The contents of the combobox depends on
744 the column in the table for which the editor is requested. Column
745 1 contains the QIcon modes, whereas column 2 contains the QIcon
746 states.
747
748 In addition, we connect the combobox's \l
749 {QComboBox::activated()}{activated()} signal to the \c
750 emitCommitData() slot to emit the
751 QAbstractItemDelegate::commitData() signal whenever the user
752 chooses an item using the combobox. This ensures that the rest of
753 the application notices the change and updates itself.
754
755 \snippet examples/widgets/icons/imagedelegate.cpp 2
756
757 The QItemDelegate::setEditorData() function is used by
758 QTableWidget to transfer data from a QTableWidgetItem to the
759 editor. The data is stored as a string; we use
760 QComboBox::findText() to locate it in the combobox.
761
762 Delegates work in terms of models, not items. This makes it
763 possible to use them with any item view class (e.g., QListView,
764 QListWidget, QTreeView, etc.). The transition between model and
765 items is done implicitly by QTableWidget; we don't need to worry
766 about it.
767
768 \snippet examples/widgets/icons/imagedelegate.cpp 3
769
770 The QItemDelegate::setEditorData() function is used by QTableWidget
771 to transfer data back from the editor to the \l{QTableWidgetItem}.
772
773 \snippet examples/widgets/icons/imagedelegate.cpp 4
774
775 The \c emitCommitData() slot simply emit the
776 QAbstractItemDelegate::commitData() signal for the editor that
777 triggered the slot. This signal must be emitted when the editor
778 widget has completed editing the data, and wants to write it back
779 into the model.
780*/
Note: See TracBrowser for help on using the repository browser.