doc/src/examples/tooltips.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     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 widgets/tooltips
       
    44     \title Tool Tips Example
       
    45 
       
    46     The Tool Tips example shows how to provide static and dynamic tool
       
    47     tips for an application's widgets.
       
    48 
       
    49     The simplest and most common way to set a widget's tool tip is by
       
    50     calling its QWidget::setToolTip() function (static tool
       
    51     tips). Then the tool tip is shown whenever the cursor points at
       
    52     the widget. We show how to do this with our application's tool
       
    53     buttons. But it is also possible to show different tool tips
       
    54     depending on the cursor's position (dynamic tooltips). This
       
    55     approach uses mouse tracking and event handling to determine what
       
    56     widgets are located under the cursor at any point in time, and
       
    57     displays their tool tips. The tool tips for the shape items in our
       
    58     application are implemented using the latter approach.
       
    59 
       
    60     \image tooltips-example.png
       
    61 
       
    62     With the \c Tooltips application the user can create new shape
       
    63     items with the provided tool buttons, and move the items around
       
    64     using the mouse. Tooltips are provided whenever the cursor is
       
    65     pointing to a shape item or one of the buttons.
       
    66 
       
    67     The Tooltips example consists of two classes:
       
    68 
       
    69     \list
       
    70     \o \c ShapeItem is a custom widget representing one single shape item.
       
    71     \o \c SortingBox inherits from QWidget and is the application's main
       
    72         widget.
       
    73     \endlist
       
    74 
       
    75     First we will review the \c SortingBox class, then we will take a
       
    76     look at the \c ShapeItem class.
       
    77 
       
    78     \section1  SortingBox Class Definition
       
    79 
       
    80     \snippet examples/widgets/tooltips/sortingbox.h 0
       
    81 
       
    82     The \c SortingBox class inherits QWidget, and it is the Tooltips
       
    83     application's main widget. We reimplement several of the event
       
    84     handlers.
       
    85 
       
    86     The \c event() function provides tooltips, the \c resize()
       
    87     function makes sure the application appears consistently when the
       
    88     user resizes the main widget, and the \c paintEvent() function
       
    89     displays the shape items within the \c SortingBox widget. The
       
    90     mouse event handlers are reimplemented to make the user able to
       
    91     move the items around.
       
    92 
       
    93     In addition we need three private slots to make the user able to
       
    94     create new shape items.
       
    95 
       
    96     \snippet examples/widgets/tooltips/sortingbox.h 1
       
    97 
       
    98     We also create several private functions: We use the \c
       
    99     initialItemPosition(), \c initialItemColor() and \c
       
   100     createToolButton() functions when we are constructing the widget,
       
   101     and we use the \c updateButtonGeometry() function whenever the
       
   102     user is resizing the application's main widget.
       
   103 
       
   104     The \c itemAt() function determines if there is a shape item at a
       
   105     particular position, and the \c moveItemTo() function moves an
       
   106     item to a new position. We use the \c createShapeItem(), \c
       
   107     randomItemPosition() and \c randomItemColor() functions to create
       
   108     new shape items.
       
   109 
       
   110     \snippet examples/widgets/tooltips/sortingbox.h 2
       
   111 
       
   112     We keep all the shape items in a QList, and we keep three
       
   113     QPainterPath objects holding the shapes of a circle, a square and
       
   114     a triangle. We also need to have a pointer to an item when it is
       
   115     moving, and we need to know its previous position.
       
   116 
       
   117     \section1 SortingBox Class Implementation
       
   118 
       
   119     \snippet examples/widgets/tooltips/sortingbox.cpp 0
       
   120 
       
   121     In the constructor, we first set the Qt::WA_StaticContents
       
   122     attribute on the widget. This attribute indicates that the widget
       
   123     contents are north-west aligned and static. On resize, such a
       
   124     widget will receive paint events only for the newly visible part
       
   125     of itself.
       
   126 
       
   127     \snippet examples/widgets/tooltips/sortingbox.cpp 1
       
   128 
       
   129     To be able to show the appropiate tooltips while the user is
       
   130     moving the cursor around, we need to enable mouse tracking for the
       
   131     widget.
       
   132 
       
   133     If mouse tracking is disabled (the default), the widget only
       
   134     receives mouse move events when at least one mouse button is
       
   135     pressed while the mouse is being moved. If mouse tracking is
       
   136     enabled, the widget receives mouse move events even if no buttons
       
   137     are pressed.
       
   138 
       
   139     \snippet examples/widgets/tooltips/sortingbox.cpp 2
       
   140 
       
   141     A widget's background role defines the brush from the widget's
       
   142     palette that is used to render the background, and QPalette::Base
       
   143     is typically white.
       
   144 
       
   145     \snippet examples/widgets/tooltips/sortingbox.cpp 3
       
   146 
       
   147     After creating the application's tool buttons using the private \c
       
   148     createToolButton() function, we construct the shapes of a circle,
       
   149     a square and a triangle using QPainterPath.
       
   150 
       
   151     The QPainterPath class provides a container for painting
       
   152     operations, enabling graphical shapes to be constructed and
       
   153     reused. The main advantage of painter paths over normal drawing
       
   154     operations is that complex shapes only need to be created once,
       
   155     but they can be drawn many times using only calls to
       
   156     QPainter::drawPath().
       
   157 
       
   158     \snippet examples/widgets/tooltips/sortingbox.cpp 4
       
   159 
       
   160     Then we set the window title, resize the widget to a suitable
       
   161     size, and finally create three initial shape items using the
       
   162     private \c createShapeItem(), \c initialItemPosition() and \c
       
   163     initialItemColor() functions.
       
   164 
       
   165     \snippet examples/widgets/tooltips/sortingbox.cpp 5
       
   166 
       
   167     QWidget::event() is the main event handler and receives all the
       
   168     widget's events. Normally, we recommend reimplementing one of the
       
   169     specialized event handlers instead of this function. But here we
       
   170     want to catch the QEvent::ToolTip events, and since these are
       
   171     rather rare, there exists no specific event handler. For that
       
   172     reason we reimplement the main event handler, and the first thing
       
   173     we need to do is to determine the event's type:
       
   174 
       
   175     \snippet examples/widgets/tooltips/sortingbox.cpp 6
       
   176 
       
   177     If the type is QEvent::ToolTip, we cast the event to a QHelpEvent,
       
   178     otherwise we propagate the event using the QWidget::event()
       
   179     function.
       
   180 
       
   181     The QHelpEvent class provides an event that is used to request
       
   182     helpful information about a particular point in a widget.
       
   183 
       
   184     For example, the QHelpEvent::pos() function returns the event's
       
   185     position relative to the widget to which the event is dispatched.
       
   186     Here we use this information to determine if the position of the
       
   187     event is contained within the area of any of the shape items. If
       
   188     it is, we display the shape item's tooltip at the position of the
       
   189     event. If not, we hide the tooltip and explicitly ignore the event.
       
   190     This makes sure that the calling code does not start any tooltip
       
   191     specific modes as a result of the event. Note that the
       
   192     QToolTip::showText() function needs the event's position in global
       
   193     coordinates provided by QHelpEvent::globalPos().
       
   194 
       
   195     \snippet examples/widgets/tooltips/sortingbox.cpp 7
       
   196 
       
   197     The \c resizeEvent() function is reimplemented to receive the
       
   198     resize events dispatched to the widget. It makes sure that the
       
   199     tool buttons keep their position relative to the main widget when
       
   200     the widget is resized. We want the buttons to always be vertically
       
   201     aligned in the application's bottom right corner, so each time the
       
   202     main widget is resized we update the buttons geometry.
       
   203 
       
   204     \snippet examples/widgets/tooltips/sortingbox.cpp 8
       
   205 
       
   206     The \c paintEvent() function is reimplemented to receive paint
       
   207     events for the widget. We create a QPainter for the \c SortingBox
       
   208     widget, and run through the list of created shape items, drawing
       
   209     each item at its defined position.
       
   210 
       
   211     \snippet examples/widgets/tooltips/sortingbox.cpp 9
       
   212 
       
   213     The painter will by default draw all the shape items at position
       
   214     (0,0) in the \c SortingBox widget. The QPainter::translate()
       
   215     function translates the coordinate system by the given offset,
       
   216     making each shape item appear at its defined position. But
       
   217     remember to translate the coordinate system back when the item is
       
   218     drawn, otherwise the next shape item will appear at a position
       
   219     relative to the item we drawed last.
       
   220 
       
   221     \snippet examples/widgets/tooltips/sortingbox.cpp 10
       
   222 
       
   223     The QPainter::setBrush() function sets the current brush used by
       
   224     the painter. When the provided argument is a QColor, the function
       
   225     calls the appropiate QBrush constructor which creates a brush with
       
   226     the specified color and Qt::SolidPattern style. The
       
   227     QPainter::drawPath() function draws the given path using the
       
   228     current pen for outline and the current brush for filling.
       
   229 
       
   230     \snippet examples/widgets/tooltips/sortingbox.cpp 11
       
   231 
       
   232     The \c mousePressEvent() function is reimplemented to receive the
       
   233     mouse press events dispatched to the widget. It determines if an
       
   234     event's position is contained within the area of any of the shape
       
   235     items, using the private \c itemAt() function.
       
   236 
       
   237     If an item covers the position, we store a pointer to that item
       
   238     and the event's position. If several of the shape items cover the
       
   239     position, we store the pointer to the uppermost item. Finally, we
       
   240     move the shape item to the end of the list, and make a call to the
       
   241     QWidget::update() function to make the item appear on top.
       
   242 
       
   243     The QWidget::update() function does not cause an immediate
       
   244     repaint; instead it schedules a paint event for processing when Qt
       
   245     returns to the main event loop.
       
   246 
       
   247     \snippet examples/widgets/tooltips/sortingbox.cpp 12
       
   248 
       
   249     The \c mouseMoveEvent() function is reimplemented to receive mouse
       
   250     move events for the widget. If the left mouse button is pressed
       
   251     and there exists a shape item in motion, we use the private \c
       
   252     moveItemTo() function to move the item with an offset
       
   253     corresponding to the offset between the positions of the current
       
   254     mouse event and the previous one.
       
   255 
       
   256     \snippet examples/widgets/tooltips/sortingbox.cpp 13
       
   257 
       
   258     The \c mouseReleaseEvent() function is reimplemented to receive
       
   259     the mouse release events dispatched to the widget. If the left
       
   260     mouse button is pressed and there exists a shape item in motion,
       
   261     we use the private \c moveItemTo() function to move the item like
       
   262     we did in \c mouseMoveEvent(). But then we remove the pointer to
       
   263     the item in motion, making the shape item's position final for
       
   264     now. To move the item further, the user will need to press the
       
   265     left mouse button again.
       
   266 
       
   267     \snippet examples/widgets/tooltips/sortingbox.cpp 14
       
   268     \codeline
       
   269     \snippet examples/widgets/tooltips/sortingbox.cpp 15
       
   270     \codeline
       
   271     \snippet examples/widgets/tooltips/sortingbox.cpp 16
       
   272 
       
   273     The \c createNewCircle(), \c createNewSquare() and \c
       
   274     createNewTriangle() slots simply create new shape items, using the
       
   275     private \c createShapeItem(), \c randomItemPosition() and \c
       
   276     randomItemColor() functions.
       
   277 
       
   278     \snippet examples/widgets/tooltips/sortingbox.cpp 17
       
   279 
       
   280     In the \c itemAt() function, we run through the list of created
       
   281     shape items to check if the given position is contained within the
       
   282     area of any of the shape items.
       
   283 
       
   284     For each shape item we use the QPainterPath::contains() function
       
   285     to find out if the item's painter path contains the position. If
       
   286     it does we return the index of the item, otherwise we return
       
   287     -1. We run through the list backwards to get the index of the
       
   288     uppermost shape item in case several items cover the position.
       
   289 
       
   290     \snippet examples/widgets/tooltips/sortingbox.cpp 18
       
   291 
       
   292     The \c moveItemTo() function moves the shape item in motion, and
       
   293     the parameter \c pos is the position of a mouse event. First we
       
   294     calculate the offset between the parameter \c pos and the previous
       
   295     mouse event position. Then we add the offset to the current
       
   296     position of the item in motion.
       
   297 
       
   298     It is tempting to simply set the position of the item to be the
       
   299     parameter \c pos. But an item's position defines the top left
       
   300     corner of the item's bounding rectangle, and the parameter \c pos
       
   301     can be any point; The suggested shortcut would cause the item to
       
   302     jump to a position where the cursor is pointing to the bounding
       
   303     rectangle's top left corner, regardless of the item's previous
       
   304     position.
       
   305 
       
   306     \snippet examples/widgets/tooltips/sortingbox.cpp 19
       
   307 
       
   308     Finally, we update the previous mouse event position, and make a
       
   309     call to the QWidget::update() function to make the item appear at
       
   310     its new position.
       
   311 
       
   312     \snippet examples/widgets/tooltips/sortingbox.cpp 20
       
   313 
       
   314     In the \c updateButtonGeometry() function we set the geometry for
       
   315     the given button. The parameter coordinates define the bottom
       
   316     right corner of the button. We use these coordinates and the
       
   317     button's size hint to determine the position of the upper left
       
   318     corner. This position, and the button's width and height, are the
       
   319     arguments required by the QWidget::setGeometry() function.
       
   320 
       
   321     In the end, we calculate and return the y-coordinate of the bottom
       
   322     right corner of the next button. We use the QWidget::style()
       
   323     function to retrieve the widget's GUI style, and then
       
   324     QStyle::pixelMetric() to determine the widget's preferred default
       
   325     spacing between its child widgets.
       
   326 
       
   327     \snippet examples/widgets/tooltips/sortingbox.cpp 21
       
   328 
       
   329     The \c createShapeItem() function creates a single shape item. It
       
   330     sets the path, tooltip, position and color, using the item's own
       
   331     functions. In the end, the function appends the new item to the
       
   332     list of shape items, and calls the QWidget::update() function to
       
   333     make it appear with the other items within the \c SortingBox
       
   334     widget.
       
   335 
       
   336     \snippet examples/widgets/tooltips/sortingbox.cpp 22
       
   337 
       
   338     The \c createToolButton() function is called from the \c
       
   339     SortingBox constructor. We create a tool button with the given
       
   340     tooltip and icon. The button's parent is the \c SortingBox widget,
       
   341     and its size is 32 x 32 pixels. Before we return the button, we
       
   342     connect it to the given slot.
       
   343 
       
   344     \snippet examples/widgets/tooltips/sortingbox.cpp 23
       
   345 
       
   346     The \c initialItemPosition() function is also called from the
       
   347     constructor. We want the three first items to initially be
       
   348     centered in the middle of the \c SortingBox widget, and we use
       
   349     this function to calculate their positions.
       
   350 
       
   351     \snippet examples/widgets/tooltips/sortingbox.cpp 24
       
   352 
       
   353     Whenever the user creates a new shape item, we want the new item
       
   354     to appear at a random position, and we use the \c
       
   355     randomItemPosition() function to calculate such a position. We
       
   356     make sure that the item appears within the visible area of the
       
   357     \c SortingBox widget, using the widget's current width and heigth
       
   358     when calculating the random coordinates.
       
   359 
       
   360     \snippet examples/widgets/tooltips/sortingbox.cpp 25
       
   361 
       
   362     As with \c initialItemPosition(), the \c initialItemColor()
       
   363     function is called from the constructor. The purposes of both
       
   364     functions are purely cosmetic: We want to control the inital
       
   365     position and color of the three first items.
       
   366 
       
   367     \snippet examples/widgets/tooltips/sortingbox.cpp 26
       
   368 
       
   369     Finally the \c randomItemColor() function is implemented to give
       
   370     the shape items the user creates, a random color.
       
   371 
       
   372     \section1 ShapeItem Class Definition
       
   373 
       
   374     \snippet examples/widgets/tooltips/shapeitem.h 0
       
   375 
       
   376     The \c ShapeItem class is a custom widget representing one single
       
   377     shape item. The widget has a path, a position, a color and a
       
   378     tooltip. We need functions to set or modify these objects, as well
       
   379     as functions that return them. We make the latter functions \c
       
   380     const to prohibit any modifications of the objects,
       
   381     i.e. prohibiting unauthorized manipulation of the shape items
       
   382     appearance.
       
   383 
       
   384     \section1 ShapeItem Class Implementation
       
   385 
       
   386     \snippet examples/widgets/tooltips/shapeitem.cpp 0
       
   387     \codeline
       
   388     \snippet examples/widgets/tooltips/shapeitem.cpp 1
       
   389     \codeline
       
   390     \snippet examples/widgets/tooltips/shapeitem.cpp 2
       
   391     \codeline
       
   392     \snippet examples/widgets/tooltips/shapeitem.cpp 3
       
   393 
       
   394     This first group of functions simply return the objects that are
       
   395     requested. The objects are returned as constants, i.e. they cannot
       
   396     be modified.
       
   397 
       
   398     \snippet examples/widgets/tooltips/shapeitem.cpp 4
       
   399     \codeline
       
   400     \snippet examples/widgets/tooltips/shapeitem.cpp 5
       
   401     \codeline
       
   402     \snippet examples/widgets/tooltips/shapeitem.cpp 6
       
   403     \codeline
       
   404     \snippet examples/widgets/tooltips/shapeitem.cpp 7
       
   405 
       
   406     The last group of functions set or modify the shape item's path,
       
   407     position, color and tooltip, respectively.
       
   408 */