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

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 33.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** 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
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
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*/
Note: See TracBrowser for help on using the repository browser.