| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example widgets/tooltips |
| \title Tool Tips Example |
| \ingroup examples-widgets |
| \brief The Tool Tips example shows how to provide static and dynamic tool |
| tips for an application's widgets. |
| |
| The simplest and most common way to set a widget's tool tip is by |
| calling its QWidget::setToolTip() function (static tool |
| tips). Then the tool tip is shown whenever the cursor points at |
| the widget. We show how to do this with our application's tool |
| buttons. But it is also possible to show different tool tips |
| depending on the cursor's position (dynamic tooltips). This |
| approach uses mouse tracking and event handling to determine what |
| widgets are located under the cursor at any point in time, and |
| displays their tool tips. The tool tips for the shape items in our |
| application are implemented using the latter approach. |
| |
| \image tooltips-example.png |
| |
| With the \c Tooltips application the user can create new shape |
| items with the provided tool buttons, and move the items around |
| using the mouse. Tooltips are provided whenever the cursor is |
| pointing to a shape item or one of the buttons. |
| |
| The Tooltips example consists of two classes: |
| |
| \list |
| \li \c ShapeItem is a custom widget representing one single shape item. |
| \li \c SortingBox inherits from QWidget and is the application's main |
| widget. |
| \endlist |
| |
| First we will review the \c SortingBox class, then we will take a |
| look at the \c ShapeItem class. |
| |
| \section1 SortingBox Class Definition |
| |
| \snippet widgets/tooltips/sortingbox.h 0 |
| |
| The \c SortingBox class inherits QWidget, and it is the Tooltips |
| application's main widget. We reimplement several of the event |
| handlers. |
| |
| The \c event() function provides tooltips, the \c resize() |
| function makes sure the application appears consistently when the |
| user resizes the main widget, and the \c paintEvent() function |
| displays the shape items within the \c SortingBox widget. The |
| mouse event handlers are reimplemented to make the user able to |
| move the items around. |
| |
| In addition we need three private slots to make the user able to |
| create new shape items. |
| |
| \snippet widgets/tooltips/sortingbox.h 1 |
| |
| We also create several private functions: We use the \c |
| initialItemPosition(), \c initialItemColor() and \c |
| createToolButton() functions when we are constructing the widget, |
| and we use the \c updateButtonGeometry() function whenever the |
| user is resizing the application's main widget. |
| |
| The \c itemAt() function determines if there is a shape item at a |
| particular position, and the \c moveItemTo() function moves an |
| item to a new position. We use the \c createShapeItem(), \c |
| randomItemPosition() and \c randomItemColor() functions to create |
| new shape items. |
| |
| \snippet widgets/tooltips/sortingbox.h 2 |
| |
| We keep all the shape items in a QVector, and we keep three |
| QPainterPath objects holding the shapes of a circle, a square and |
| a triangle. We also need to have a pointer to an item when it is |
| moving, and we need to know its previous position. |
| |
| \section1 SortingBox Class Implementation |
| |
| \snippet widgets/tooltips/sortingbox.cpp 0 |
| |
| In the constructor, we first set the Qt::WA_StaticContents |
| attribute on the widget. This attribute indicates that the widget |
| contents are north-west aligned and static. On resize, such a |
| widget will receive paint events only for the newly visible part |
| of itself. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 1 |
| |
| To be able to show the appropriate tooltips while the user is |
| moving the cursor around, we need to enable mouse tracking for the |
| widget. |
| |
| If mouse tracking is disabled (the default), the widget only |
| receives mouse move events when at least one mouse button is |
| pressed while the mouse is being moved. If mouse tracking is |
| enabled, the widget receives mouse move events even if no buttons |
| are pressed. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 2 |
| |
| A widget's background role defines the brush from the widget's |
| palette that is used to render the background, and QPalette::Base |
| is typically white. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 3 |
| |
| After creating the application's tool buttons using the private \c |
| createToolButton() function, we construct the shapes of a circle, |
| a square and a triangle using QPainterPath. |
| |
| The QPainterPath class provides a container for painting |
| operations, enabling graphical shapes to be constructed and |
| reused. The main advantage of painter paths over normal drawing |
| operations is that complex shapes only need to be created once, |
| but they can be drawn many times using only calls to |
| QPainter::drawPath(). |
| |
| \snippet widgets/tooltips/sortingbox.cpp 4 |
| |
| Then we set the window title, resize the widget to a suitable |
| size, and finally create three initial shape items using the |
| private \c createShapeItem(), \c initialItemPosition() and \c |
| initialItemColor() functions. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 5 |
| |
| QWidget::event() is the main event handler and receives all the |
| widget's events. Normally, we recommend reimplementing one of the |
| specialized event handlers instead of this function. But here we |
| want to catch the QEvent::ToolTip events, and since these are |
| rather rare, there exists no specific event handler. For that |
| reason we reimplement the main event handler, and the first thing |
| we need to do is to determine the event's type: |
| |
| \snippet widgets/tooltips/sortingbox.cpp 6 |
| |
| If the type is QEvent::ToolTip, we cast the event to a QHelpEvent, |
| otherwise we propagate the event using the QWidget::event() |
| function. |
| |
| The QHelpEvent class provides an event that is used to request |
| helpful information about a particular point in a widget. |
| |
| For example, the QHelpEvent::pos() function returns the event's |
| position relative to the widget to which the event is dispatched. |
| Here we use this information to determine if the position of the |
| event is contained within the area of any of the shape items. If |
| it is, we display the shape item's tooltip at the position of the |
| event. If not, we hide the tooltip and explicitly ignore the event. |
| This makes sure that the calling code does not start any tooltip |
| specific modes as a result of the event. Note that the |
| QToolTip::showText() function needs the event's position in global |
| coordinates provided by QHelpEvent::globalPos(). |
| |
| \snippet widgets/tooltips/sortingbox.cpp 7 |
| |
| The \c resizeEvent() function is reimplemented to receive the |
| resize events dispatched to the widget. It makes sure that the |
| tool buttons keep their position relative to the main widget when |
| the widget is resized. We want the buttons to always be vertically |
| aligned in the application's bottom right corner, so each time the |
| main widget is resized we update the buttons geometry. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 8 |
| |
| The \c paintEvent() function is reimplemented to receive paint |
| events for the widget. We create a QPainter for the \c SortingBox |
| widget, and run through the list of created shape items, drawing |
| each item at its defined position. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 9 |
| |
| The painter will by default draw all the shape items at position |
| (0,0) in the \c SortingBox widget. The QPainter::translate() |
| function translates the coordinate system by the given offset, |
| making each shape item appear at its defined position. But |
| remember to translate the coordinate system back when the item is |
| drawn, otherwise the next shape item will appear at a position |
| relative to the item we drawed last. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 10 |
| |
| The QPainter::setBrush() function sets the current brush used by |
| the painter. When the provided argument is a QColor, the function |
| calls the appropriate QBrush constructor which creates a brush with |
| the specified color and Qt::SolidPattern style. The |
| QPainter::drawPath() function draws the given path using the |
| current pen for outline and the current brush for filling. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 11 |
| |
| The \c mousePressEvent() function is reimplemented to receive the |
| mouse press events dispatched to the widget. It determines if an |
| event's position is contained within the area of any of the shape |
| items, using the private \c itemAt() function. |
| |
| If an item covers the position, we store a pointer to that item |
| and the event's position. If several of the shape items cover the |
| position, we store the pointer to the uppermost item. Finally, we |
| move the shape item to the end of the list, and make a call to the |
| QWidget::update() function to make the item appear on top. |
| |
| The QWidget::update() function does not cause an immediate |
| repaint; instead it schedules a paint event for processing when Qt |
| returns to the main event loop. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 12 |
| |
| The \c mouseMoveEvent() function is reimplemented to receive mouse |
| move events for the widget. If the left mouse button is pressed |
| and there exists a shape item in motion, we use the private \c |
| moveItemTo() function to move the item with an offset |
| corresponding to the offset between the positions of the current |
| mouse event and the previous one. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 13 |
| |
| The \c mouseReleaseEvent() function is reimplemented to receive |
| the mouse release events dispatched to the widget. If the left |
| mouse button is pressed and there exists a shape item in motion, |
| we use the private \c moveItemTo() function to move the item like |
| we did in \c mouseMoveEvent(). But then we remove the pointer to |
| the item in motion, making the shape item's position final for |
| now. To move the item further, the user will need to press the |
| left mouse button again. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 14 |
| \codeline |
| \snippet widgets/tooltips/sortingbox.cpp 15 |
| \codeline |
| \snippet widgets/tooltips/sortingbox.cpp 16 |
| |
| The \c createNewCircle(), \c createNewSquare() and \c |
| createNewTriangle() slots simply create new shape items, using the |
| private \c createShapeItem(), \c randomItemPosition() and \c |
| randomItemColor() functions. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 17 |
| |
| In the \c itemAt() function, we run through the list of created |
| shape items to check if the given position is contained within the |
| area of any of the shape items. |
| |
| For each shape item we use the QPainterPath::contains() function |
| to find out if the item's painter path contains the position. If |
| it does we return the index of the item, otherwise we return |
| -1. We run through the list backwards to get the index of the |
| uppermost shape item in case several items cover the position. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 18 |
| |
| The \c moveItemTo() function moves the shape item in motion, and |
| the parameter \c pos is the position of a mouse event. First we |
| calculate the offset between the parameter \c pos and the previous |
| mouse event position. Then we add the offset to the current |
| position of the item in motion. |
| |
| It is tempting to simply set the position of the item to be the |
| parameter \c pos. But an item's position defines the top left |
| corner of the item's bounding rectangle, and the parameter \c pos |
| can be any point; The suggested shortcut would cause the item to |
| jump to a position where the cursor is pointing to the bounding |
| rectangle's top left corner, regardless of the item's previous |
| position. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 19 |
| |
| Finally, we update the previous mouse event position, and make a |
| call to the QWidget::update() function to make the item appear at |
| its new position. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 20 |
| |
| In the \c updateButtonGeometry() function we set the geometry for |
| the given button. The parameter coordinates define the bottom |
| right corner of the button. We use these coordinates and the |
| button's size hint to determine the position of the upper left |
| corner. This position, and the button's width and height, are the |
| arguments required by the QWidget::setGeometry() function. |
| |
| In the end, we calculate and return the y-coordinate of the bottom |
| right corner of the next button. We use the QWidget::style() |
| function to retrieve the widget's GUI style, and then |
| QStyle::pixelMetric() to determine the widget's preferred default |
| spacing between its child widgets. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 21 |
| |
| The \c createShapeItem() function creates a single shape item. It |
| sets the path, tooltip, position and color, using the item's own |
| functions. In the end, the function appends the new item to the |
| list of shape items, and calls the QWidget::update() function to |
| make it appear with the other items within the \c SortingBox |
| widget. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 22 |
| |
| The \c createToolButton() function is called from the \c |
| SortingBox constructor. We create a tool button with the given |
| tooltip and icon. The button's parent is the \c SortingBox widget, |
| and its size is 32 x 32 pixels. Before we return the button, we |
| connect it to the given slot. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 23 |
| |
| The \c initialItemPosition() function is also called from the |
| constructor. We want the three first items to initially be |
| centered in the middle of the \c SortingBox widget, and we use |
| this function to calculate their positions. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 24 |
| |
| Whenever the user creates a new shape item, we want the new item |
| to appear at a random position, and we use the \c |
| randomItemPosition() function to calculate such a position. We |
| make sure that the item appears within the visible area of the |
| \c SortingBox widget, using the widget's current width and height |
| when calculating the random coordinates. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 25 |
| |
| As with \c initialItemPosition(), the \c initialItemColor() |
| function is called from the constructor. The purposes of both |
| functions are purely cosmetic: We want to control the initial |
| position and color of the three first items. |
| |
| \snippet widgets/tooltips/sortingbox.cpp 26 |
| |
| Finally the \c randomItemColor() function is implemented to give |
| the shape items the user creates, a random color. |
| |
| \section1 ShapeItem Class Definition |
| |
| \snippet widgets/tooltips/shapeitem.h 0 |
| |
| The \c ShapeItem class is a custom widget representing one single |
| shape item. The widget has a path, a position, a color and a |
| tooltip. We need functions to set or modify these objects, as well |
| as functions that return them. We make the latter functions \c |
| const to prohibit any modifications of the objects, |
| i.e. prohibiting unauthorized manipulation of the shape items |
| appearance. |
| |
| \section1 ShapeItem Class Implementation |
| |
| \snippet widgets/tooltips/shapeitem.cpp 0 |
| \codeline |
| \snippet widgets/tooltips/shapeitem.cpp 1 |
| \codeline |
| \snippet widgets/tooltips/shapeitem.cpp 2 |
| \codeline |
| \snippet widgets/tooltips/shapeitem.cpp 3 |
| |
| This first group of functions simply return the objects that are |
| requested. The objects are returned as constants, i.e. they cannot |
| be modified. |
| |
| \snippet widgets/tooltips/shapeitem.cpp 4 |
| \codeline |
| \snippet widgets/tooltips/shapeitem.cpp 5 |
| \codeline |
| \snippet widgets/tooltips/shapeitem.cpp 6 |
| \codeline |
| \snippet widgets/tooltips/shapeitem.cpp 7 |
| |
| The last group of functions set or modify the shape item's path, |
| position, color and tooltip, respectively. |
| */ |