diff options
author | Alexis Menard <alexis.menard@nokia.com> | 2009-04-17 14:06:06 (GMT) |
---|---|---|
committer | Alexis Menard <alexis.menard@nokia.com> | 2009-04-17 14:06:06 (GMT) |
commit | f15b8a83e2e51955776a3f07cb85ebfc342dd8ef (patch) | |
tree | c5dc684986051654898db11ce73e03b9fec8db99 /doc/src/examples/collidingmice-example.qdoc | |
download | Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.zip Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.tar.gz Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.tar.bz2 |
Initial import of statemachine branch from the old kinetic repository
Diffstat (limited to 'doc/src/examples/collidingmice-example.qdoc')
-rw-r--r-- | doc/src/examples/collidingmice-example.qdoc | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/doc/src/examples/collidingmice-example.qdoc b/doc/src/examples/collidingmice-example.qdoc new file mode 100644 index 0000000..7ea2ca2 --- /dev/null +++ b/doc/src/examples/collidingmice-example.qdoc @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/collidingmice + \title Colliding Mice Example + + The Colliding Mice example shows how to use the Graphics View + framework to implement animated items and detect collision between + items. + + \image collidingmice-example.png + + Graphics View provides the QGraphicsScene class for managing and + interacting with a large number of custom-made 2D graphical items + derived from the QGraphicsItem class, and a QGraphicsView widget + for visualizing the items, with support for zooming and rotation. + + The example consists of an item class and a main function: + the \c Mouse class represents the individual mice extending + QGraphicsItem, and the \c main() function provides the main + application window. + + We will first review the \c Mouse class to see how to animate + items and detect item collision, and then we will review the \c + main() function to see how to put the items into a scene and how to + implement the corresponding view. + + \section1 Mouse Class Definition + + The \c mouse class inherits both QObject and QGraphicsItem. The + QGraphicsItem class is the base class for all graphical items in + the Graphics View framework, and provides a light-weight + foundation for writing your own custom items. + + \snippet examples/graphicsview/collidingmice/mouse.h 0 + + When writing a custom graphics item, you must implement + QGraphicsItem's two pure virtual public functions: \l + {QGraphicsItem::}{boundingRect()}, which returns an estimate of + the area painted by the item, and \l {QGraphicsItem::}{paint()}, + which implements the actual painting. In addition, we reimplement + the \l {QGraphicsItem::}{shape()} function to return an accurate + shape of our mouse item; the default implementation simply returns + the item's bounding rectangle. + + The rationale for deriving from QObject in addition to + QGraphicsItem is to be able to animate our items by reimplementing + QObject's \l {QObject::}{timerEvent()} function and use + QObject::startTimer() to generate timer events. + + \section1 Mouse Class Definition + + When constructing a mouse item, we first ensure that all the item's + private variables are properly initialized: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 0 + + To calculate the various components of the mouse's color, we use + the global qrand() function which is a thread-safe version of the + standard C++ rand() function. + + Then we call the \l {QGraphicsItem::rotate()}{rotate()} function + inherited from QGraphicsItem. Items live in their own local + coordinate system. Their coordinates are usually centered around + (0, 0), and this is also the center for all transformations. By + calling the item's \l {QGraphicsItem::rotate()}{rotate()} function + we alter the direction in which the mouse will start moving. + + In the end we call QObject's \l {QObject::}{startTimer()} + function, emitting a timer event every 1000/33 millisecond. This + enables us to animate our mouse item using our reimplementation of + the \l {QObject::}{timerEvent()} function; whenever a mouse + receives a timer event it will trigger \l + {QObject::}{timerEvent()}: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 4 + \snippet examples/graphicsview/collidingmice/mouse.cpp 5 + \snippet examples/graphicsview/collidingmice/mouse.cpp 6 + + First we ensure that the mice stays within a circle with a radius + of 150 pixels. + + Note the \l {QGraphicsItem::mapFromScene()}{mapFromScene()} + function provided by QGraphicsItem. This function maps a position + given in \e scene coordinates, to the item's coordinate system. + + \snippet examples/graphicsview/collidingmice/mouse.cpp 7 + \snippet examples/graphicsview/collidingmice/mouse.cpp 8 + \snippet examples/graphicsview/collidingmice/mouse.cpp 9 + \codeline + \snippet examples/graphicsview/collidingmice/mouse.cpp 10 + + Then we try to avoid colliding with other mice. + + \snippet examples/graphicsview/collidingmice/mouse.cpp 11 + + Finally, we calculate the mouse's speed and its eye direction (for + use when painting the mouse), and set its new position. + + The position of an item describes its origin (local coordinate (0, + 0)) in the parent coordinates. The \l {QGraphicsItem::setPos()} + function sets the position of the item to the given position in + the parent's coordinate system. For items with no parent, the + given position is interpreted as scene coordinates. QGraphicsItem + also provides a \l {QGraphicsItem::}{mapToParent()} function to + map a position given in item coordinates, to the parent's + coordinate system. If the item has no parent, the position will be + mapped to the scene's coordinate system instead. + + Then it is time to provide an implementation for the pure virtual + functions inherited from QGraphicsItem. Let's first take a look at + the \l {QGraphicsItem::}{boundingRect()} function: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 1 + + The \l {QGraphicsItem::boundingRect()}{boundingRect()} function + defines the outer bounds of the item as a rectangle. Note that the + Graphics View framework uses the bounding rectangle to determine + whether the item requires redrawing, so all painting must be + restricted inside this rectangle. + + \snippet examples/graphicsview/collidingmice/mouse.cpp 3 + + The Graphics View framework calls the \l + {QGraphicsItem::paint()}{paint()} function to paint the contents + of the item; the function paints the item in local coordinates. + + Note the painting of the ears: Whenever a mouse item collides with + other mice items its ears are filled with red; otherwise they are + filled with dark yellow. We use the + QGraphicsScene::collidingItems() function to check if there are + any colliding mice. The actual collision detection is handled by + the Graphics View framework using shape-shape intersection. All we + have to do is to ensure that the QGraphicsItem::shape() function + returns an accurate shape for our item: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 2 + + Because the complexity of arbitrary shape-shape intersection grows + with an order of magnitude when the shapes are complex, this + operation can be noticably time consuming. An alternative approach + is to reimplement the \l + {QGraphicsItem::collidesWithItem()}{collidesWithItem()} function + to provide your own custom item and shape collision algorithm. + + This completes the \c Mouse class implementation, it is now ready + for use. Let's take a look at the \c main() function to see how to + implement a scene for the mice and a view for displaying the + contents of the scene. + + \section1 The Main() Function + + In this example we have chosen to let the \c main() function + provide the main application window, creating the items and the + scene, putting the items into the scene and creating a + corresponding view. + + \snippet examples/graphicsview/collidingmice/main.cpp 0 + + First, we create an application object and call the global + qsrand() function to specify the seed used to generate a new + random number sequence of pseudo random integers with the + previously mentioned qrand() function. + + Then it is time to create the scene: + + \snippet examples/graphicsview/collidingmice/main.cpp 1 + + The QGraphicsScene class serves as a container for + QGraphicsItems. It also provides functionality that lets you + efficiently determine the location of items as well as determining + which items that are visible within an arbitrary area on the + scene. + + When creating a scene it is recommended to set the scene's + rectangle, i.e., the rectangle that defines the extent of the + scene. It is primarily used by QGraphicsView to determine the + view's default scrollable area, and by QGraphicsScene to manage + item indexing. If not explicitly set, the scene's default + rectangle will be the largest bounding rectangle of all the items + on the scene since the scene was created (i.e., the rectangle will + grow when items are added or moved in the scene, but it will never + shrink). + + \snippet examples/graphicsview/collidingmice/main.cpp 2 + + The item index function is used to speed up item discovery. \l + {QGraphicsScene::NoIndex}{NoIndex} implies that item location is + of linear complexity, as all items on the scene are + searched. Adding, moving and removing items, however, is done in + constant time. This approach is ideal for dynamic scenes, where + many items are added, moved or removed continuously. The + alternative is \l {QGraphicsScene::BspTreeIndex}{BspTreeIndex} + which makes use of binary search resulting in item location + algorithms that are of an order closer to logarithmic complexity. + + \snippet examples/graphicsview/collidingmice/main.cpp 3 + + Then we add the mice to the scene. + + \snippet examples/graphicsview/collidingmice/main.cpp 4 + + To be able to view the scene we must also create a QGraphicsView + widget. The QGraphicsView class visualizes the contents of a scene + in a scrollable viewport. We also ensure that the contents is + rendered using antialiasing, and we create the cheese background + by setting the view's background brush. + + The image used for the background is stored as a binary file in + the application's executable using Qt's \l {The Qt Resource + System}{resource system}. The QPixmap constructor accepts both + file names that refer to actual files on disk and file names that + refer to the application's embedded resources. + + \snippet examples/graphicsview/collidingmice/main.cpp 5 + + Then we set the cache mode; QGraphicsView can cache pre-rendered + content in a pixmap, which is then drawn onto the viewport. The + purpose of such caching is to speed up the total rendering time + for areas that are slow to render, e.g., texture, gradient and + alpha blended backgrounds. The \l + {QGraphicsView::CacheMode}{CacheMode} property holds which parts + of the view that are cached, and the \l + {QGraphicsView::CacheBackground}{CacheBackground} flag enables + caching of the view's background. + + By setting the \l {QGraphicsView::dragMode}{dragMode} property we + define what should happen when the user clicks on the scene + background and drags the mouse. The \l + {QGraphicsView::ScrollHandDrag}{ScrollHandDrag} flag makes the + cursor change into a pointing hand, and dragging the mouse around + will scroll the scrollbars. + + \snippet examples/graphicsview/collidingmice/main.cpp 6 + + In the end, we set the application window's title and size before + we enter the main event loop using the QApplication::exec() + function. +*/ + |