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