1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the documentation of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
26 ****************************************************************************/
29 \example widgets/tooltips
30 \title Tool Tips Example
32 The Tool Tips example shows how to provide static and dynamic tool
33 tips for an application's widgets.
35 The simplest and most common way to set a widget's tool tip is by
36 calling its QWidget::setToolTip() function (static tool
37 tips). Then the tool tip is shown whenever the cursor points at
38 the widget. We show how to do this with our application's tool
39 buttons. But it is also possible to show different tool tips
40 depending on the cursor's position (dynamic tooltips). This
41 approach uses mouse tracking and event handling to determine what
42 widgets are located under the cursor at any point in time, and
43 displays their tool tips. The tool tips for the shape items in our
44 application are implemented using the latter approach.
46 \image tooltips-example.png
48 With the \c Tooltips application the user can create new shape
49 items with the provided tool buttons, and move the items around
50 using the mouse. Tooltips are provided whenever the cursor is
51 pointing to a shape item or one of the buttons.
53 The Tooltips example consists of two classes:
56 \li \c ShapeItem is a custom widget representing one single shape item.
57 \li \c SortingBox inherits from QWidget and is the application's main
61 First we will review the \c SortingBox class, then we will take a
62 look at the \c ShapeItem class.
64 \section1 SortingBox Class Definition
66 \snippet examples/widgets/tooltips/sortingbox.h 0
68 The \c SortingBox class inherits QWidget, and it is the Tooltips
69 application's main widget. We reimplement several of the event
72 The \c event() function provides tooltips, the \c resize()
73 function makes sure the application appears consistently when the
74 user resizes the main widget, and the \c paintEvent() function
75 displays the shape items within the \c SortingBox widget. The
76 mouse event handlers are reimplemented to make the user able to
77 move the items around.
79 In addition we need three private slots to make the user able to
80 create new shape items.
82 \snippet examples/widgets/tooltips/sortingbox.h 1
84 We also create several private functions: We use the \c
85 initialItemPosition(), \c initialItemColor() and \c
86 createToolButton() functions when we are constructing the widget,
87 and we use the \c updateButtonGeometry() function whenever the
88 user is resizing the application's main widget.
90 The \c itemAt() function determines if there is a shape item at a
91 particular position, and the \c moveItemTo() function moves an
92 item to a new position. We use the \c createShapeItem(), \c
93 randomItemPosition() and \c randomItemColor() functions to create
96 \snippet examples/widgets/tooltips/sortingbox.h 2
98 We keep all the shape items in a QList, and we keep three
99 QPainterPath objects holding the shapes of a circle, a square and
100 a triangle. We also need to have a pointer to an item when it is
101 moving, and we need to know its previous position.
103 \section1 SortingBox Class Implementation
105 \snippet examples/widgets/tooltips/sortingbox.cpp 0
107 In the constructor, we first set the Qt::WA_StaticContents
108 attribute on the widget. This attribute indicates that the widget
109 contents are north-west aligned and static. On resize, such a
110 widget will receive paint events only for the newly visible part
113 \snippet examples/widgets/tooltips/sortingbox.cpp 1
115 To be able to show the appropriate tooltips while the user is
116 moving the cursor around, we need to enable mouse tracking for the
119 If mouse tracking is disabled (the default), the widget only
120 receives mouse move events when at least one mouse button is
121 pressed while the mouse is being moved. If mouse tracking is
122 enabled, the widget receives mouse move events even if no buttons
125 \snippet examples/widgets/tooltips/sortingbox.cpp 2
127 A widget's background role defines the brush from the widget's
128 palette that is used to render the background, and QPalette::Base
131 \snippet examples/widgets/tooltips/sortingbox.cpp 3
133 After creating the application's tool buttons using the private \c
134 createToolButton() function, we construct the shapes of a circle,
135 a square and a triangle using QPainterPath.
137 The QPainterPath class provides a container for painting
138 operations, enabling graphical shapes to be constructed and
139 reused. The main advantage of painter paths over normal drawing
140 operations is that complex shapes only need to be created once,
141 but they can be drawn many times using only calls to
142 QPainter::drawPath().
144 \snippet examples/widgets/tooltips/sortingbox.cpp 4
146 Then we set the window title, resize the widget to a suitable
147 size, and finally create three initial shape items using the
148 private \c createShapeItem(), \c initialItemPosition() and \c
149 initialItemColor() functions.
151 \snippet examples/widgets/tooltips/sortingbox.cpp 5
153 QWidget::event() is the main event handler and receives all the
154 widget's events. Normally, we recommend reimplementing one of the
155 specialized event handlers instead of this function. But here we
156 want to catch the QEvent::ToolTip events, and since these are
157 rather rare, there exists no specific event handler. For that
158 reason we reimplement the main event handler, and the first thing
159 we need to do is to determine the event's type:
161 \snippet examples/widgets/tooltips/sortingbox.cpp 6
163 If the type is QEvent::ToolTip, we cast the event to a QHelpEvent,
164 otherwise we propagate the event using the QWidget::event()
167 The QHelpEvent class provides an event that is used to request
168 helpful information about a particular point in a widget.
170 For example, the QHelpEvent::pos() function returns the event's
171 position relative to the widget to which the event is dispatched.
172 Here we use this information to determine if the position of the
173 event is contained within the area of any of the shape items. If
174 it is, we display the shape item's tooltip at the position of the
175 event. If not, we hide the tooltip and explicitly ignore the event.
176 This makes sure that the calling code does not start any tooltip
177 specific modes as a result of the event. Note that the
178 QToolTip::showText() function needs the event's position in global
179 coordinates provided by QHelpEvent::globalPos().
181 \snippet examples/widgets/tooltips/sortingbox.cpp 7
183 The \c resizeEvent() function is reimplemented to receive the
184 resize events dispatched to the widget. It makes sure that the
185 tool buttons keep their position relative to the main widget when
186 the widget is resized. We want the buttons to always be vertically
187 aligned in the application's bottom right corner, so each time the
188 main widget is resized we update the buttons geometry.
190 \snippet examples/widgets/tooltips/sortingbox.cpp 8
192 The \c paintEvent() function is reimplemented to receive paint
193 events for the widget. We create a QPainter for the \c SortingBox
194 widget, and run through the list of created shape items, drawing
195 each item at its defined position.
197 \snippet examples/widgets/tooltips/sortingbox.cpp 9
199 The painter will by default draw all the shape items at position
200 (0,0) in the \c SortingBox widget. The QPainter::translate()
201 function translates the coordinate system by the given offset,
202 making each shape item appear at its defined position. But
203 remember to translate the coordinate system back when the item is
204 drawn, otherwise the next shape item will appear at a position
205 relative to the item we drawed last.
207 \snippet examples/widgets/tooltips/sortingbox.cpp 10
209 The QPainter::setBrush() function sets the current brush used by
210 the painter. When the provided argument is a QColor, the function
211 calls the appropriate QBrush constructor which creates a brush with
212 the specified color and Qt::SolidPattern style. The
213 QPainter::drawPath() function draws the given path using the
214 current pen for outline and the current brush for filling.
216 \snippet examples/widgets/tooltips/sortingbox.cpp 11
218 The \c mousePressEvent() function is reimplemented to receive the
219 mouse press events dispatched to the widget. It determines if an
220 event's position is contained within the area of any of the shape
221 items, using the private \c itemAt() function.
223 If an item covers the position, we store a pointer to that item
224 and the event's position. If several of the shape items cover the
225 position, we store the pointer to the uppermost item. Finally, we
226 move the shape item to the end of the list, and make a call to the
227 QWidget::update() function to make the item appear on top.
229 The QWidget::update() function does not cause an immediate
230 repaint; instead it schedules a paint event for processing when Qt
231 returns to the main event loop.
233 \snippet examples/widgets/tooltips/sortingbox.cpp 12
235 The \c mouseMoveEvent() function is reimplemented to receive mouse
236 move events for the widget. If the left mouse button is pressed
237 and there exists a shape item in motion, we use the private \c
238 moveItemTo() function to move the item with an offset
239 corresponding to the offset between the positions of the current
240 mouse event and the previous one.
242 \snippet examples/widgets/tooltips/sortingbox.cpp 13
244 The \c mouseReleaseEvent() function is reimplemented to receive
245 the mouse release events dispatched to the widget. If the left
246 mouse button is pressed and there exists a shape item in motion,
247 we use the private \c moveItemTo() function to move the item like
248 we did in \c mouseMoveEvent(). But then we remove the pointer to
249 the item in motion, making the shape item's position final for
250 now. To move the item further, the user will need to press the
251 left mouse button again.
253 \snippet examples/widgets/tooltips/sortingbox.cpp 14
255 \snippet examples/widgets/tooltips/sortingbox.cpp 15
257 \snippet examples/widgets/tooltips/sortingbox.cpp 16
259 The \c createNewCircle(), \c createNewSquare() and \c
260 createNewTriangle() slots simply create new shape items, using the
261 private \c createShapeItem(), \c randomItemPosition() and \c
262 randomItemColor() functions.
264 \snippet examples/widgets/tooltips/sortingbox.cpp 17
266 In the \c itemAt() function, we run through the list of created
267 shape items to check if the given position is contained within the
268 area of any of the shape items.
270 For each shape item we use the QPainterPath::contains() function
271 to find out if the item's painter path contains the position. If
272 it does we return the index of the item, otherwise we return
273 -1. We run through the list backwards to get the index of the
274 uppermost shape item in case several items cover the position.
276 \snippet examples/widgets/tooltips/sortingbox.cpp 18
278 The \c moveItemTo() function moves the shape item in motion, and
279 the parameter \c pos is the position of a mouse event. First we
280 calculate the offset between the parameter \c pos and the previous
281 mouse event position. Then we add the offset to the current
282 position of the item in motion.
284 It is tempting to simply set the position of the item to be the
285 parameter \c pos. But an item's position defines the top left
286 corner of the item's bounding rectangle, and the parameter \c pos
287 can be any point; The suggested shortcut would cause the item to
288 jump to a position where the cursor is pointing to the bounding
289 rectangle's top left corner, regardless of the item's previous
292 \snippet examples/widgets/tooltips/sortingbox.cpp 19
294 Finally, we update the previous mouse event position, and make a
295 call to the QWidget::update() function to make the item appear at
298 \snippet examples/widgets/tooltips/sortingbox.cpp 20
300 In the \c updateButtonGeometry() function we set the geometry for
301 the given button. The parameter coordinates define the bottom
302 right corner of the button. We use these coordinates and the
303 button's size hint to determine the position of the upper left
304 corner. This position, and the button's width and height, are the
305 arguments required by the QWidget::setGeometry() function.
307 In the end, we calculate and return the y-coordinate of the bottom
308 right corner of the next button. We use the QWidget::style()
309 function to retrieve the widget's GUI style, and then
310 QStyle::pixelMetric() to determine the widget's preferred default
311 spacing between its child widgets.
313 \snippet examples/widgets/tooltips/sortingbox.cpp 21
315 The \c createShapeItem() function creates a single shape item. It
316 sets the path, tooltip, position and color, using the item's own
317 functions. In the end, the function appends the new item to the
318 list of shape items, and calls the QWidget::update() function to
319 make it appear with the other items within the \c SortingBox
322 \snippet examples/widgets/tooltips/sortingbox.cpp 22
324 The \c createToolButton() function is called from the \c
325 SortingBox constructor. We create a tool button with the given
326 tooltip and icon. The button's parent is the \c SortingBox widget,
327 and its size is 32 x 32 pixels. Before we return the button, we
328 connect it to the given slot.
330 \snippet examples/widgets/tooltips/sortingbox.cpp 23
332 The \c initialItemPosition() function is also called from the
333 constructor. We want the three first items to initially be
334 centered in the middle of the \c SortingBox widget, and we use
335 this function to calculate their positions.
337 \snippet examples/widgets/tooltips/sortingbox.cpp 24
339 Whenever the user creates a new shape item, we want the new item
340 to appear at a random position, and we use the \c
341 randomItemPosition() function to calculate such a position. We
342 make sure that the item appears within the visible area of the
343 \c SortingBox widget, using the widget's current width and height
344 when calculating the random coordinates.
346 \snippet examples/widgets/tooltips/sortingbox.cpp 25
348 As with \c initialItemPosition(), the \c initialItemColor()
349 function is called from the constructor. The purposes of both
350 functions are purely cosmetic: We want to control the initial
351 position and color of the three first items.
353 \snippet examples/widgets/tooltips/sortingbox.cpp 26
355 Finally the \c randomItemColor() function is implemented to give
356 the shape items the user creates, a random color.
358 \section1 ShapeItem Class Definition
360 \snippet examples/widgets/tooltips/shapeitem.h 0
362 The \c ShapeItem class is a custom widget representing one single
363 shape item. The widget has a path, a position, a color and a
364 tooltip. We need functions to set or modify these objects, as well
365 as functions that return them. We make the latter functions \c
366 const to prohibit any modifications of the objects,
367 i.e. prohibiting unauthorized manipulation of the shape items
370 \section1 ShapeItem Class Implementation
372 \snippet examples/widgets/tooltips/shapeitem.cpp 0
374 \snippet examples/widgets/tooltips/shapeitem.cpp 1
376 \snippet examples/widgets/tooltips/shapeitem.cpp 2
378 \snippet examples/widgets/tooltips/shapeitem.cpp 3
380 This first group of functions simply return the objects that are
381 requested. The objects are returned as constants, i.e. they cannot
384 \snippet examples/widgets/tooltips/shapeitem.cpp 4
386 \snippet examples/widgets/tooltips/shapeitem.cpp 5
388 \snippet examples/widgets/tooltips/shapeitem.cpp 6
390 \snippet examples/widgets/tooltips/shapeitem.cpp 7
392 The last group of functions set or modify the shape item's path,
393 position, color and tooltip, respectively.