|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
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 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 /*! |
|
43 \example itemviews/stardelegate |
|
44 \title Star Delegate Example |
|
45 |
|
46 The Star Delegate example shows how to create a delegate that |
|
47 can paint itself and that supports editing. |
|
48 |
|
49 \image stardelegate.png The Star Delegate Example |
|
50 |
|
51 When displaying data in a QListView, QTableView, or QTreeView, |
|
52 the individual items are drawn by a |
|
53 \l{Delegate Classes}{delegate}. Also, when the user starts |
|
54 editing an item (e.g., by double-clicking the item), the delegate |
|
55 provides an editor widget that is placed on top of the item while |
|
56 editing takes place. |
|
57 |
|
58 Delegates are subclasses of QAbstractItemDelegate. Qt provides |
|
59 QItemDelegate, which inherits QAbstractItemDelegate and handles |
|
60 the most common data types (notably \c int and QString). If we |
|
61 need to support custom data types, or want to customize the |
|
62 rendering or the editing for existing data types, we can subclass |
|
63 QAbstractItemDelegate or QItemDelegate. See \l{Delegate Classes} |
|
64 for more information about delegates, and \l{Model/View |
|
65 Programming} if you need a high-level introduction to Qt's |
|
66 model/view architecture (including delegates). |
|
67 |
|
68 In this example, we will see how to implement a custom delegate |
|
69 to render and edit a "star rating" data type, which can store |
|
70 values such as "1 out of 5 stars". |
|
71 |
|
72 The example consists of the following classes: |
|
73 |
|
74 \list |
|
75 \o \c StarRating is the custom data type. It stores a rating |
|
76 expressed as stars, such as "2 out of 5 stars" or "5 out of |
|
77 6 stars". |
|
78 |
|
79 \o \c StarDelegate inherits QItemDelegate and provides support |
|
80 for \c StarRating (in addition to the data types already |
|
81 handled by QItemDelegate). |
|
82 |
|
83 \o \c StarEditor inherits QWidget and is used by \c StarDelegate |
|
84 to let the user edit a star rating using the mouse. |
|
85 \endlist |
|
86 |
|
87 To show the \c StarDelegate in action, we will fill a |
|
88 QTableWidget with some data and install the delegate on it. |
|
89 |
|
90 \section1 StarDelegate Class Definition |
|
91 |
|
92 Here's the definition of the \c StarDelegate class: |
|
93 |
|
94 \snippet examples/itemviews/stardelegate/stardelegate.h 0 |
|
95 |
|
96 All public functions are reimplemented virtual functions from |
|
97 QItemDelegate to provide custom rendering and editing. |
|
98 |
|
99 \section1 StarDelegate Class Implementation |
|
100 |
|
101 The \l{QAbstractItemDelegate::}{paint()} function is |
|
102 reimplemented from QItemDelegate and is called whenever the view |
|
103 needs to repaint an item: |
|
104 |
|
105 \snippet examples/itemviews/stardelegate/stardelegate.cpp 0 |
|
106 |
|
107 The function is invoked once for each item, represented by a |
|
108 QModelIndex object from the model. If the data stored in the item |
|
109 is a \c StarRating, we paint it ourselves; otherwise, we let |
|
110 QItemDelegate paint it for us. This ensures that the \c |
|
111 StarDelegate can handle the most common data types. |
|
112 |
|
113 In the case where the item is a \c StarRating, we draw the |
|
114 background if the item is selected, and we draw the item using \c |
|
115 StarRating::paint(), which we will review later. |
|
116 |
|
117 \c{StartRating}s can be stored in a QVariant thanks to the |
|
118 Q_DECLARE_METATYPE() macro appearing in \c starrating.h. More on |
|
119 this later. |
|
120 |
|
121 The \l{QAbstractItemDelegate::}{createEditor()} function is |
|
122 called when the user starts editing an item: |
|
123 |
|
124 \snippet examples/itemviews/stardelegate/stardelegate.cpp 2 |
|
125 |
|
126 If the item is a \c StarRating, we create a \c StarEditor and |
|
127 connect its \c editingFinished() signal to our \c |
|
128 commitAndCloseEditor() slot, so we can update the model when the |
|
129 editor closes. |
|
130 |
|
131 Here's the implementation of \c commitAndCloseEditor(): |
|
132 |
|
133 \snippet examples/itemviews/stardelegate/stardelegate.cpp 5 |
|
134 |
|
135 When the user is done editing, we emit |
|
136 \l{QAbstractItemDelegate::}{commitData()} and |
|
137 \l{QAbstractItemDelegate::}{closeEditor()} (both declared in |
|
138 QAbstractItemDelegate), to tell the model that there is edited |
|
139 data and to inform the view that the editor is no longer needed. |
|
140 |
|
141 The \l{QAbstractItemDelegate::}{setEditorData()} function is |
|
142 called when an editor is created to initialize it with data |
|
143 from the model: |
|
144 |
|
145 \snippet examples/itemviews/stardelegate/stardelegate.cpp 3 |
|
146 |
|
147 We simply call \c setStarRating() on the editor. |
|
148 |
|
149 The \l{QAbstractItemDelegate::}{setModelData()} function is |
|
150 called when editing is finished, to commit data from the editor |
|
151 to the model: |
|
152 |
|
153 \snippet examples/itemviews/stardelegate/stardelegate.cpp 4 |
|
154 |
|
155 The \c sizeHint() function returns an item's preferred size: |
|
156 |
|
157 \snippet examples/itemviews/stardelegate/stardelegate.cpp 1 |
|
158 |
|
159 We simply forward the call to \c StarRating. |
|
160 |
|
161 \section1 StarEditor Class Definition |
|
162 |
|
163 The \c StarEditor class was used when implementing \c |
|
164 StarDelegate. Here's the class definition: |
|
165 |
|
166 \snippet examples/itemviews/stardelegate/stareditor.h 0 |
|
167 |
|
168 The class lets the user edit a \c StarRating by moving the mouse |
|
169 over the editor. It emits the \c editingFinished() signal when |
|
170 the user clicks on the editor. |
|
171 |
|
172 The protected functions are reimplemented from QWidget to handle |
|
173 mouse and paint events. The private function \c starAtPosition() |
|
174 is a helper function that returns the number of the star under |
|
175 the mouse pointer. |
|
176 |
|
177 \section1 StarEditor Class Implementation |
|
178 |
|
179 Let's start with the constructor: |
|
180 |
|
181 \snippet examples/itemviews/stardelegate/stareditor.cpp 0 |
|
182 |
|
183 We enable \l{QWidget::setMouseTracking()}{mouse tracking} on the |
|
184 widget so we can follow the cursor even when the user doesn't |
|
185 hold down any mouse button. We also turn on QWidget's |
|
186 \l{QWidget::autoFillBackground}{auto-fill background} feature to |
|
187 obtain an opaque background. (Without the call, the view's |
|
188 background would shine through the editor.) |
|
189 |
|
190 The \l{QWidget::}{paintEvent()} function is reimplemented from |
|
191 QWidget: |
|
192 |
|
193 \snippet examples/itemviews/stardelegate/stareditor.cpp 1 |
|
194 |
|
195 We simply call \c StarRating::paint() to draw the stars, just |
|
196 like we did when implementing \c StarDelegate. |
|
197 |
|
198 \snippet examples/itemviews/stardelegate/stareditor.cpp 2 |
|
199 |
|
200 In the mouse event handler, we call \c setStarCount() on the |
|
201 private data member \c myStarRating to reflect the current cursor |
|
202 position, and we call QWidget::update() to force a repaint. |
|
203 |
|
204 \snippet examples/itemviews/stardelegate/stareditor.cpp 3 |
|
205 |
|
206 When the user releases a mouse button, we simply emit the \c |
|
207 editingFinished() signal. |
|
208 |
|
209 \snippet examples/itemviews/stardelegate/stareditor.cpp 4 |
|
210 |
|
211 The \c starAtPosition() function uses basic linear algebra to |
|
212 find out which star is under the cursor. |
|
213 |
|
214 \section1 StarRating Class Definition |
|
215 |
|
216 \snippet examples/itemviews/stardelegate/starrating.h 0 |
|
217 \codeline |
|
218 \snippet examples/itemviews/stardelegate/starrating.h 1 |
|
219 |
|
220 The \c StarRating class represents a rating as a number of stars. |
|
221 In addition to holding the data, it is also capable of painting |
|
222 the stars on a QPaintDevice, which in this example is either a |
|
223 view or an editor. The \c myStarCount member variable stores the |
|
224 current rating, and \c myMaxStarCount stores the highest possible |
|
225 rating (typically 5). |
|
226 |
|
227 The Q_DECLARE_METATYPE() macro makes the type \c StarRating known |
|
228 to QVariant, making it possible to store \c StarRating values in |
|
229 QVariant. |
|
230 |
|
231 \section1 StarRating Class Implementation |
|
232 |
|
233 The constructor initializes \c myStarCount and \c myMaxStarCount, |
|
234 and sets up the polygons used to draw stars and diamonds: |
|
235 |
|
236 \snippet examples/itemviews/stardelegate/starrating.cpp 0 |
|
237 |
|
238 The \c paint() function paints the stars in this \c StarRating |
|
239 object on a paint device: |
|
240 |
|
241 \snippet examples/itemviews/stardelegate/starrating.cpp 2 |
|
242 |
|
243 We first set the pen and brush we will use for painting. The \c |
|
244 mode parameter can be either \c Editable or \c ReadOnly. If \c |
|
245 mode is editable, we use the \l{QPalette::}{Highlight} color |
|
246 instead of the \l{QPalette::}{Foreground} color to draw the |
|
247 stars. |
|
248 |
|
249 Then we draw the stars. If we are in \c Edit mode, we paint |
|
250 diamonds in place of stars if the rating is less than the highest |
|
251 rating. |
|
252 |
|
253 The \c sizeHint() function returns the preferred size for an area |
|
254 to paint the stars on: |
|
255 |
|
256 \snippet examples/itemviews/stardelegate/starrating.cpp 1 |
|
257 |
|
258 The preferred size is just enough to paint the maximum number of |
|
259 stars. The function is called by both \c StarDelegate::sizeHint() |
|
260 and \c StarEditor::sizeHint(). |
|
261 |
|
262 \section1 The \c main() Function |
|
263 |
|
264 Here's the program's \c main() function: |
|
265 |
|
266 \snippet examples/itemviews/stardelegate/main.cpp 5 |
|
267 |
|
268 The \c main() function creates a QTableWidget and sets a \c |
|
269 StarDelegate on it. \l{QAbstractItemView::}{DoubleClicked} and |
|
270 \l{QAbstractItemView::}{SelectedClicked} are set as |
|
271 \l{QAbstractItemView::editTriggers()}{edit triggers}, so that the |
|
272 editor is opened with a single click when the star rating item is |
|
273 selected. |
|
274 |
|
275 The \c populateTableWidget() function fills the QTableWidget with |
|
276 data: |
|
277 |
|
278 \snippet examples/itemviews/stardelegate/main.cpp 0 |
|
279 \snippet examples/itemviews/stardelegate/main.cpp 1 |
|
280 \dots |
|
281 \snippet examples/itemviews/stardelegate/main.cpp 2 |
|
282 \snippet examples/itemviews/stardelegate/main.cpp 3 |
|
283 \codeline |
|
284 \snippet examples/itemviews/stardelegate/main.cpp 4 |
|
285 |
|
286 Notice the call to qVariantFromValue to convert a \c |
|
287 StarRating to a QVariant. |
|
288 |
|
289 \section1 Possible Extensions and Suggestions |
|
290 |
|
291 There are many ways to customize Qt's \l{Model/View |
|
292 Programming}{model/view framework}. The approach used in this |
|
293 example is appropriate for most custom delegates and editors. |
|
294 Examples of possibilities not used by the star delegate and star |
|
295 editor are: |
|
296 |
|
297 \list |
|
298 \o It is possible to open editors programmatically by calling |
|
299 QAbstractItemView::edit(), instead of relying on edit |
|
300 triggers. This could be use to support other edit triggers |
|
301 than those offered by the QAbstractItemView::EditTrigger enum. |
|
302 For example, in the Star Delegate example, hovering over an |
|
303 item with the mouse might make sense as a way to pop up an |
|
304 editor. |
|
305 |
|
306 \o By reimplementing QAbstractItemDelegate::editorEvent(), it is |
|
307 possible to implement the editor directly in the delegate, |
|
308 instead of creating a separate QWidget subclass. |
|
309 \endlist |
|
310 */ |