source: trunk/doc/src/examples/pixelator.qdoc@ 651

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

trunk: Merged in qt 4.6.2 sources.

File size: 11.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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 [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example itemviews/pixelator
44 \title Pixelator Example
45
46 The Pixelator example shows how delegates can be used to customize the way that
47 items are rendered in standard item views.
48
49 \image pixelator-example.png
50
51 By default, QTreeView, QTableView, and QListView use a standard item delegate
52 to display and edit a set of common data types that are sufficient for many
53 applications. However, an application may need to represent items of data in a
54 particular way, or provide support for rendering more specialized data types,
55 and this often requires the use of a custom delegate.
56
57 In this example, we show how to use custom delegates to modify the appearance
58 of standard views. To do this, we implement the following components:
59
60 \list
61 \i A model which represents each pixel in an image as an item of data, where each
62 item contains a value for the brightness of the corresponding pixel.
63 \i A custom delegate that uses the information supplied by the model to represent
64 each pixel as a black circle on a white background, where the radius of the
65 circle corresponds to the darkness of the pixel.
66 \endlist
67
68 This example may be useful for developers who want to implement their own table
69 models or custom delegates. The process of creating custom delegates for editing
70 item data is covered in the \l{Spin Box Delegate Example}{Spin Box Delegate}
71 example.
72
73 \section1 ImageModel Class Definition
74
75 The \c ImageModel class is defined as follows:
76
77 \snippet examples/itemviews/pixelator/imagemodel.h 0
78
79 Since we only require a simple, read-only table model, we only need to implement
80 functions to indicate the dimensions of the image and supply data to other
81 components.
82
83 For convenience, the image to be used is passed in the constructor.
84
85 \section1 ImageModel Class Implementation
86
87 The constructor is trivial:
88
89 \snippet examples/itemviews/pixelator/imagemodel.cpp 0
90
91 The \c setImage() function sets the image that will be used by the model:
92
93 \snippet examples/itemviews/pixelator/imagemodel.cpp 1
94
95 The QAbstractItemModel::reset() call tells the view(s) that the model
96 has changed.
97
98 The \c rowCount() and \c columnCount() functions return the height and width of
99 the image respectively:
100
101 \snippet examples/itemviews/pixelator/imagemodel.cpp 2
102 \snippet examples/itemviews/pixelator/imagemodel.cpp 3
103
104 Since the image is a simple two-dimensional structure, the \c parent arguments
105 to these functions are unused. They both simply return the relevant size from
106 the underlying image object.
107
108 The \c data() function returns data for the item that corresponds to a given
109 model index in a format that is suitable for a particular role:
110
111 \snippet examples/itemviews/pixelator/imagemodel.cpp 4
112
113 In this implementation, we only check that the model index is valid, and that
114 the role requested is the \l{Qt::ItemDataRole}{DisplayRole}. If so, the function
115 returns the grayscale value of the relevant pixel in the image; otherwise, a null
116 model index is returned.
117
118 This model can be used with QTableView to display the integer brightness values
119 for the pixels in the image. However, we will implement a custom delegate to
120 display this information in a more artistic way.
121
122 The \c headerData() function is also reimplemented:
123
124 \snippet examples/itemviews/pixelator/imagemodel.cpp 5
125
126 We return (1, 1) as the size hint for a header item. If we
127 didn't, the headers would default to a larger size, preventing
128 us from displaying really small items (which can be specified
129 using the \gui{Pixel size} combobox).
130
131 \section1 PixelDelegate Class Definition
132
133 The \c PixelDelegate class is defined as follows:
134
135 \snippet examples/itemviews/pixelator/pixeldelegate.h 0
136
137 This class provides only basic features for a delegate so, unlike the
138 \l{Spin Box Delegate Example}{Spin Box Delegate} example, we subclass
139 QAbstractItemDelegate instead of QItemDelegate.
140
141 We only need to reimplement \l{QAbstractItemDelegate::paint()}{paint()} and
142 \l{QAbstractItemDelegate::sizeHint()}{sizeHint()} in this class.
143 However, we also provide a delegate-specific \c setPixelSize() function so
144 that we can change the delegate's behavior via the signals and slots mechanism.
145
146 \section1 PixelDelegate Class Implementation
147
148 The \c PixelDelegate constructor is used to set up a default value for
149 the size of each "pixel" that it renders. The base class constructor is
150 also called to ensure that the delegate is set up with a parent object,
151 if one is supplied:
152
153 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 0
154
155 Each item is rendered by the delegate's
156 \l{QAbstractItemDelegate::paint()}{paint()} function. The view calls this
157 function with a ready-to-use QPainter object, style information that the
158 delegate should use to correctly draw the item, and an index to the item in
159 the model:
160
161 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 1
162
163 The first task the delegate has to perform is to draw the item's background
164 correctly. Usually, selected items appear differently to non-selected items,
165 so we begin by testing the state passed in the style option and filling the
166 background if necessary.
167
168 The radius of each circle is calculated in the following lines of code:
169
170 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 3
171 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 4
172
173 First, the largest possible radius of the circle is determined by taking the
174 smallest dimension of the style option's \c rect attribute.
175 Using the model index supplied, we obtain a value for the brightness of the
176 relevant pixel in the image. The radius of the circle is calculated by
177 scaling the brightness to fit within the item and subtracting it from the
178 largest possible radius.
179
180 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 5
181 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 6
182 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 7
183
184 We save the painter's state, turn on antialiasing (to obtain smoother
185 curves), and turn off the pen.
186
187 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 8
188 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 9
189
190 The foreground of the item (the circle representing a pixel) must be
191 rendered using an appropriate brush. For unselected items, we will use a
192 solid black brush; selected items are drawn using a predefined brush from
193 the style option's palette.
194
195 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 10
196
197 Finally, we paint the circle within the rectangle specified by the style
198 option and we call \l{QPainter::}{restore()} on the painter.
199
200 The \c paint() function does not have to be particularly complicated; it is
201 only necessary to ensure that the state of the painter when the function
202 returns is the same as it was when it was called. This usually
203 means that any transformations applied to the painter must be preceded by
204 a call to QPainter::save() and followed by a call to QPainter::restore().
205
206 The delegate's \l{QAbstractItemDelegate::}{sizeHint()} function
207 returns a size for the item based on the predefined pixel size, initially set
208 up in the constructor:
209
210 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 11
211
212 The delegate's size is updated whenever the pixel size is changed.
213 We provide a custom slot to do this:
214
215 \snippet examples/itemviews/pixelator/pixeldelegate.cpp 12
216
217 \section1 Using The Custom Delegate
218
219 In this example, we use a main window to display a table of data, using the
220 custom delegate to render each cell in a particular way. Much of the
221 \c MainWindow class performs tasks that are not related to item views. Here,
222 we only quote the parts that are relevant. You can look at the rest of the
223 implementation by following the links to the code at the top of this
224 document.
225
226 In the constructor, we set up a table view, turn off its grid, and hide its
227 headers:
228
229 \snippet examples/itemviews/pixelator/mainwindow.cpp 0
230 \dots
231 \snippet examples/itemviews/pixelator/mainwindow.cpp 1
232
233 This enables the items to be drawn without any gaps between them. Removing
234 the headers also prevents the user from adjusting the sizes of individual
235 rows and columns.
236
237 We also set the minimum section size to 1 on the headers. If we
238 didn't, the headers would default to a larger size, preventing
239 us from displaying really small items (which can be specified
240 using the \gui{Pixel size} combobox).
241
242 The custom delegate is constructed with the main window as its parent, so
243 that it will be deleted correctly later, and we set it on the table view.
244
245 \snippet examples/itemviews/pixelator/mainwindow.cpp 2
246
247 Each item in the table view will be rendered by the \c PixelDelegate
248 instance.
249
250 We construct a spin box to allow the user to change the size of each "pixel"
251 drawn by the delegate:
252
253 \snippet examples/itemviews/pixelator/mainwindow.cpp 3
254
255 This spin box is connected to the custom slot we implemented in the
256 \c PixelDelegate class. This ensures that the delegate always draws each
257 pixel at the currently specified size:
258
259 \snippet examples/itemviews/pixelator/mainwindow.cpp 4
260 \dots
261 \snippet examples/itemviews/pixelator/mainwindow.cpp 5
262
263 We also connect the spin box to a slot in the \c MainWindow class. This
264 forces the view to take into account the new size hints for each item;
265 these are provided by the delegate in its \c sizeHint() function.
266
267 \snippet examples/itemviews/pixelator/mainwindow.cpp 6
268
269 We explicitly resize the columns and rows to match the
270 \gui{Pixel size} combobox.
271*/
Note: See TracBrowser for help on using the repository browser.