diff options
Diffstat (limited to 'doc')
104 files changed, 2842 insertions, 56 deletions
diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc new file mode 100644 index 0000000..b4e603c --- /dev/null +++ b/doc/src/animation.qdoc @@ -0,0 +1,368 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \page animation-overview.html + \title The Animation Framework + \ingroup architecture + \ingroup animation + \brief An overview of the Animation Framework + + \keyword Animation + + The animation framework is part of the Kinetic project, and aims + to provide an easy way for creating animated and smooth GUI's. By + animating Qt properties, the framework provides great freedom for + animating widgets and other \l{QObject}s. The framework can also + be used with the Graphics View framework. + + In this overview, we explain the basics of its architecture. We + also show examples of the most common techniques that the + framework allows for animating QObjects and graphics items. + + \tableofcontents + + \section1 The Animation Architecture + + We will in this section take a high-level look at the animation + framework's architecture and how it is used to animate Qt + properties. The following diagram shows the most important classes + in the animation framework. + + \image animations-architecture.png + + The animation framework foundation consists of the base class + QAbstractAnimation, and its two subclasses QVariantAnimation and + QAnimationGroup. QAbstractAnimation is the ancestor of all + animations. It represents basic properties that are common for all + animations in the framework; notably, the ability to start, stop, + and pause an animation. It is also receives the time change + notifications. + + The animation framework further provides the QPropertyAnimation + class, which inherits QVariantAnimation and performs animation of + a Qt property, which is part of Qt's \l{Meta-Object + System}{meta-object system}. The class performs an interpolation + over the property using an easing curve. So when you want to + animate a value, you can declare it as a property and make your + class a QObject. Note that this gives us great freedom in + animating already existing widgets and other \l{QObject}s. + + Complex animations can be constructed by building a tree structure + of \l{QAbstractAnimation}s. The tree is built by using + \l{QAnimationGroup}s, which function as containers for other + animations. Note also that the groups are subclasses of + QAbstractAnimation, so groups can themselves contain other groups. + + The animation framework can be used on its own, but is also + designed to be part of the state machine framework (See the + \l{The State Machine Framework}{state machine framework} for an + introduction to the Qt state machine). The state machine provides + a special state that can play an animation. A QState can also set + properties when the state is entered or exited, and this special + animation state will interpolate between these values when given a + QPropertyAnimation. We will look more closely at this later. + + Behind the scenes, the animations are controlled by a global + timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to + all animations that are playing. + + For detailed descriptions of the classes' function and roles in + the framework, please look up their class descriptions. + + \section1 Animating Qt Properties + + As mentioned in the previous section, the QPropertyAnimation class + can interpolate over Qt properties. It is this class that should + be used for animation of values; in fact, its superclass, + QVariantAnimation, is an abstract class, and cannot be used + directly. + + A major reason we chose to animate Qt properties is that it + presents us with freedom to animate already existing classes in + the Qt API. Notably, the QWidget class (which we can also embed in + a QGraphicsView) has properties for its bounds, colors, etc. + Let's look at a small example: + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation animation(&button, "geometry"); + animation.setDuration(10000); + animation.setStartValue(QRect(0, 0, 100, 30)); + animation.setEndValue(QRect(250, 250, 100, 30)); + + animation.start(); + \endcode + + This code will move \c button from the top left corner of the + screen to the position (250, 250) in 10 seconds (10000 milliseconds). + + The example above will do a linear interpolation between the + start and end value. It is also possible to set values + situated between the start and end value. The interpolation + will then go by these points. + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation animation(&button, "geometry"); + animation.setDuration(10000); + + animation.setKeyValueAt(0, QRect(0, 0, 100, 30)); + animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30)); + animation.setKeyValueAt(1, QRect(0, 0, 100, 30)); + + animation.start(); + \endcode + + In this example, the animation will take the button to (250, 250) + in 8 seconds, and then move it back to its original position in + the remaining 2 seconds. The movement will be linearly + interpolated between these points. + + You also have the possibility to animate values of a QObject + that is not declared as a Qt property. The only requirement is + that this value has a setter. You can then subclass the class + containing the value and declare a property that uses this setter. + Note that each Qt property requires a getter, so you will need to + provide a getter yourself if this is not defined. + + \code + class MyGraphicsRectItem : public QObject, public QGraphicsRectItem + { + Q_OBJECT + Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) + }; + \endcode + + In the above code example, we subclass QGraphicsRectItem and + define a geometry property. We can now animate the widgets + geometry even if QGraphicsRectItem does not provide the geometry + property. + + For a general introduction to the Qt property system, see its + \l{Qt's Property System}{overview}. + + \section1 Animations and the Graphics View Framework + + When you want to animate \l{QGraphicsItem}s, you also use + QPropertyAnimation. However, QGraphicsItem does not inherit QObject. + A good solution is to subclass the graphics item you wish to animate. + This class will then also inherit QObject. + This way, QPropertyAnimation can be used for \l{QGraphicsItem}s. + The example below shows how this is done. Another possibility is + to inherit QGraphicsWidget, which already is a QObject. + + \code + class Pixmap : public QObject, public QGraphicsPixmapItem + { + Q_OBJECT + Q_PROPERTY(QPointF pos READ pos WRITE setPos) + ... + \endcode + + As described in the previous section, we need to define + properties that we wish to animate. + + Note that QObject must be the first class inherited as the + meta-object system demands this. + + \warning The QItemAnimation class, which was initially intended + for animating \l{QGraphicsItem}s may be deprecated or removed from + the animation framework. + + \omit (need something about the list of animations). \endomit + + \section1 Easing Curves + + As mentioned, QPropertyAnimation performs an interpolation between + the start and end property value. In addition to adding more key + values to the animation, you can also use an easing curve. Easing + curves describe a function that controls how the speed of the + interpolation between 0 and 1 should be, and are useful if you + want to control the speed of an animation without changing the + path of the interpolation. + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation animation(&button, "geometry"); + animation.setDuration(3000); + animation.setStartValue(QRect(0, 0, 100, 30)); + animation.setEndValue(QRect(250, 250, 100, 30)); + + animation.setEasingCurve(QEasingCurve::OutBounce); + + animation.start(); + \endcode + + Here the animation will follow a curve that makes it bounce like a + ball as if it was dropped from the start to the end position. + QEasingCurve has a large collection of curves for you to choose + from. These are defined by the QEasingCurve::Type enum. If you are + in need of another curve, you can also implement one yourself, and + register it with QEasingCurve. + + \omit Drop this for the first Lab release + (Example of custom easing curve (without the actual impl of + the function I expect) + \endomit + + \section1 Putting Animations Together + + An application will often contain more than one animation. For + instance, you might want to move more than one graphics item + simultaneously or move them in sequence after each other. + + The subclasses of QAnimationGroup (QSequentialAnimationGroup and + QParallelAnimationGroup) are containers for other animations so + that these animations can be animated either in sequence or + parallel. The QAnimationGroup is an example of an animation that + does not animate properties, but it gets notified of time changes + periodically. This enables it to forward those time changes to its + contained animations, and thereby controlling when its animations + are played. + + Let's look at code examples that use both + QSequentialAnimationGroup and QParallelAnimationGroup, starting + off with the latter. + + \code + QPushButton *bonnie = new QPushButton("Bonnie"); + bonnie->show(); + + QPushButton *clyde = new QPushButton("Clyde"); + clyde->show(); + + QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); + // Set up anim1 + + QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry"); + // Set up anim2 + + QParallelAnimationGroup *group = new QParallelAnimationGroup; + group->addAnimation(anim1); + group->addAnimation(anim2); + + group->start(); + \endcode + + A parallel group plays more than one animation at the same time. + Calling its \l{QAbstractAnimation::}{start()} function will start + all animations it governs. + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation anim1(&button, "geometry"); + anim1.setDuration(3000); + anim1.setStartValue(QRect(0, 0, 100, 30)); + anim1.setEndValue(QRect(500, 500, 100, 30)); + + QPropertyAnimation anim2(&button, "geometry"); + anim2.setDuration(3000); + anim2.setStartValue(QRect(500, 500, 100, 30)); + anim2.setEndValue(QRect(1000, 500, 100, 30)); + + QSequentialAnimationGroup group; + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + group.start(); + \endcode + + As you no doubt have guessed, QSequentialAnimationGroup plays + its animations in sequence. It starts the next animation in + the list after the previous is finished. + + Since an animation group is an animation itself, you can add + it to another group. This way, you can build a tree structure + of animations which specifies when the animations are played + in relation to each other. + + \section1 Animations and States + + When using a \l{The State Machine Framework}{state machine}, we + have a special state, QAnimationState, that will play one or more + animations. + + The QState::addAnimatedTransition() convenience function lets you + associate an animation to a state transition. The function will + create the QAnimationState for you, and insert it into the state + machine. We also have the possibility to associate properties with + the states rather than setting the start and end values ourselves. + Below is a complete code example that animates the geometry of a + QPushButton. + + \code + QPushButton *button = new QPushButton("Animated Button"); + button->show(); + + QStateMachine *machine = new QStateMachine; + + QState *state1 = new QState(machine->rootState()); + state1->setPropertyOnEntry(button, "geometry", + QRect(0, 0, 100, 30)); + machine->setInitialState(state1); + + QState *state2 = new QState(machine->rootState()); + state2->setPropertyOnEntry(button, "geometry", + QRect(250, 250, 100, 30)); + + state1->addAnimatedTransition(button, SIGNAL(clicked()), state2, + new QPropertyAnimation(button, "geometry")); + state2->addAnimatedTransition(button, SIGNAL(clicked()), state1, + new QPropertyAnimation(button, "geometry")); + + machine->start(); + \endcode + + For a more comprehensive example of how to use the state machine + framework for animations, see the states example (it lives in the + \c{examples/animation/states} directory). +*/ + diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 4b8de32..ee240b5 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -2401,12 +2401,106 @@ pixmap property in the property editor. is used to hide widgets that should not be explicitly created by the user, but are required by other widgets. - If you would like to use a container widget that is not a subclass of the - containers provided in \QD, but the container is still based on the notion - of \e{Current Page}, you need to provide a container extension and - tell \QD which method to use to add the pages. This can be done using the - \c{<addpagemethod>} XML tag. + + A complete custom widget specification looks like: + + \code +<ui language="c++"> displayname="MyWidget"> + <widget class="widgets::MyWidget" name="mywidget"/> + <customwidgets> + <customwidget> + <class>widgets::MyWidget</class> + <addpagemethod>addPage</addpagemethod> + <propertyspecifications> + <stringpropertyspecification name="fileName" notr="true" type="singleline" + <stringpropertyspecification name="text" type="richtext" + </propertyspecifications> + </customwidget> + </customwidgets> +</ui> + \endcode + + Attributes of the \c{<ui>} tag: + \table + \header + \o Attribute + \o Presence + \o Values + \o Comment + \row + \o \c{language} + \o optional + \o "c++", "jambi" + \o This attribute specifies the language the custom widget is intended for. + It is mainly there to prevent C++-plugins from appearing in Qt Jambi. + \row + \o \c{displayname} + \o optional + \o Class name + \o The value of the attribute appears in the Widget box and can be used to + strip away namespaces. + \endtable + + The \c{<addpagemethod>} tag tells \QD and \l uic which method should be used to + add pages to a container widget. This applies to container widgets that require + calling a particular method to add a child rather than adding the child by passing + the parent. In particular, this is relevant for containers that are not a + a subclass of the containers provided in \QD, but are based on the notion + of \e{Current Page}. In addition, you need to provide a container extension + for them. + + The \c{<propertyspecifications>} element can contain a list of property meta information. + Currently, properties of type string are supported. For these properties, the + \c{<stringpropertyspecification>} tag can be used. This tag has the following attributes: + + + \table + \header + \o Attribute + \o Presence + \o Values + \o Comment + \row + \o \c{name} + \o required + \o Name of the property + \row + \o \c{type} + \o required + \o See below table + \o The value of the attribute determines how the property editor will handle them. + \row + \o \c{notr} + \o optional + \o "true", "false" + \o If the attribute is "true", the value is not meant to be translated. + \endtable + + Values of the \c{type} attribute of the string property: + \table + \header + \o Value + \o Type + \row + \o \c{"richtext"} + \o Rich text. + \row + \o \c{"multiline"} + \o Multi-line plain text. + \row + \o \c{"singleline"} + \o Single-line plain text. + \row + \o \c{"stylesheet"} + \o A CSS-style sheet. + \row + \o \c{"objectname"} + \o An object name (restricted set of valid characters). + \row + \o \c{"url"} + \o URL, file name. + \endtable \section1 Plugin Requirements diff --git a/doc/src/diagrams/animations-architecture.svg b/doc/src/diagrams/animations-architecture.svg new file mode 100644 index 0000000..0246510 --- /dev/null +++ b/doc/src/diagrams/animations-architecture.svg @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="950.00006" + height="365.28983" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docname="animations-architecture.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.0"> + <defs + id="defs4"> + <marker + inkscape:stockid="Arrow2Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow2Mend" + style="overflow:visible"> + <path + id="path3736" + style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z" + transform="scale(-0.6,-0.6)" /> + </marker> + <marker + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0" + refX="0" + id="Arrow2Lend" + style="overflow:visible"> + <path + id="path3730" + style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z" + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Lend" + style="overflow:visible"> + <path + id="path3712" + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" + transform="matrix(-0.8,0,0,-0.8,-10,0)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL" + style="overflow:visible"> + <path + id="path3852" + d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" + transform="scale(0.8,0.8)" /> + </marker> + <linearGradient + id="linearGradient3165"> + <stop + style="stop-color:#c8c8dc;stop-opacity:1;" + offset="0" + id="stop3167" /> + <stop + style="stop-color:#b4b4c8;stop-opacity:0;" + offset="1" + id="stop3169" /> + </linearGradient> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3165" + id="linearGradient3171" + x1="249.25" + y1="89.862183" + x2="475.75" + y2="89.862183" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.2195969,0,0,3.7006494,-257.93754,-842.42203)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3165" + id="linearGradient3183" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.2195969,0,0,3.7006494,-383.02298,-676.69717)" + x1="249.25" + y1="89.862183" + x2="475.75" + y2="89.862183" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3165" + id="linearGradient3191" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.2195969,0,0,3.7006494,-382.93759,-1004.922)" + x1="249.25" + y1="89.862183" + x2="475.75" + y2="89.862183" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3165" + id="linearGradient7165" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.2195969,0,0,3.7006494,-483.69907,-593.77419)" + x1="249.25" + y1="89.862183" + x2="475.75" + y2="89.862183" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3165" + id="linearGradient7195" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.2195969,0,0,3.7006494,-571.87523,-1167.422)" + x1="249.25" + y1="89.862183" + x2="475.75" + y2="89.862183" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3165" + id="linearGradient7203" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.2195969,0,0,3.7006494,-572.46592,-841.2256)" + x1="249.25" + y1="89.862183" + x2="475.75" + y2="89.862183" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.98994949" + inkscape:cx="276.75951" + inkscape:cy="155.06417" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:snap-bbox="true" + inkscape:window-width="1592" + inkscape:window-height="1124" + inkscape:window-x="0" + inkscape:window-y="0"> + <inkscape:grid + type="xygrid" + id="grid2383" + visible="true" + enabled="true" + units="pt" + spacingx="2pt" + spacingy="2pt" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-121.77519,-152.95286)"> + <rect + style="opacity:1;fill:url(#linearGradient3171);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect2385" + width="49.409317" + height="277.54871" + x="-203.03828" + y="-648.64777" + ry="12.582828" + rx="10.562523" + transform="matrix(0,-1,-1,0,0,0)" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono" + x="380.311" + y="185.86879" + id="text3173" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan3175" + x="380.311" + y="185.86879">QAbstractAnimation</tspan></text> + <rect + style="opacity:1;fill:url(#linearGradient3183);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3177" + width="49.409317" + height="277.54871" + x="-328.12369" + y="-482.92297" + ry="12.582828" + rx="10.562523" + transform="matrix(0,-1,-1,0,0,0)" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono" + x="221.80489" + y="310.95419" + id="text3179" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan3181" + x="221.80489" + y="310.95419">QVariantAnimation</tspan></text> + <rect + style="opacity:1;fill:url(#linearGradient3191);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3185" + width="49.409317" + height="277.54871" + x="-328.03827" + y="-811.14777" + ry="12.582828" + rx="10.562523" + transform="matrix(0,-1,-1,0,0,0)" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono" + x="564.13324" + y="310.86877" + id="text3187" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan3189" + x="564.13324" + y="310.86877">QAnimationGroup</tspan></text> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 346.77519,279.39048 L 346.77519,241.89048 L 509.27519,241.89048 L 509.27519,204.39048" + id="path3195" + sodipodi:nodetypes="cccc" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 671.77519,279.39048 L 671.77519,241.89048 L 509.27519,241.89048" + id="path7137" + sodipodi:nodetypes="ccc" /> + <rect + style="opacity:1;fill:url(#linearGradient7165);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect7159" + width="49.409317" + height="277.54871" + x="-428.7998" + y="-400" + ry="12.582828" + rx="10.562523" + transform="matrix(0,-1,-1,0,0,0)" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono" + x="131.66315" + y="411.63031" + id="text7161" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan7163" + x="131.66315" + y="411.63031">QPropertyAnimation</tspan></text> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 309.27519,379.39048 L 309.27519,329.39048" + id="path7167" + sodipodi:nodetypes="cc" /> + <rect + style="opacity:1;fill:url(#linearGradient7195);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect7189" + width="49.409317" + height="375" + x="-516.97589" + y="-1071.0991" + ry="12.582828" + rx="10.562523" + transform="matrix(0,-1,-1,0,0,0)" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono" + x="703.17139" + y="499.8064" + id="text7191" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan7193" + x="703.17139" + y="499.8064">QSequentialAnimationGroup</tspan></text> + <rect + style="opacity:1;fill:url(#linearGradient7203);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect7197" + width="50" + height="350" + x="-517.56659" + y="-647.45129" + ry="12.582828" + rx="10.562523" + transform="matrix(0,-1,-1,0,0,0)" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono" + x="306.46109" + y="500.39709" + id="text7199" + sodipodi:linespacing="100%"><tspan + sodipodi:role="line" + id="tspan7201" + x="306.46109" + y="500.39709">QParallelAnimationGroup</tspan></text> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 859.27519,466.89048 L 859.27519,391.89048 L 671.77519,391.89048" + id="path7205" + sodipodi:nodetypes="ccc" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 496.77519,466.89048 L 496.77519,391.89048 L 671.77519,391.89048 L 671.77519,329.39048" + id="path7207" + sodipodi:nodetypes="cccc" /> + </g> +</svg> diff --git a/doc/src/diagrams/programs/easingcurve/easingcurve.pro b/doc/src/diagrams/programs/easingcurve/easingcurve.pro new file mode 100644 index 0000000..0b80127 --- /dev/null +++ b/doc/src/diagrams/programs/easingcurve/easingcurve.pro @@ -0,0 +1,13 @@ +###################################################################### +# Automatically generated by qmake (2.01a) fr 13. feb 13:26:38 2009 +###################################################################### + +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp + +CONFIG += console
\ No newline at end of file diff --git a/doc/src/diagrams/programs/easingcurve/main.cpp b/doc/src/diagrams/programs/easingcurve/main.cpp new file mode 100644 index 0000000..98e9d37 --- /dev/null +++ b/doc/src/diagrams/programs/easingcurve/main.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +void createCurveIcons(); + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + createCurveIcons(); + return app.exit(); +} + +void createCurveIcons() +{ + QDir dir(QDir::current()); + if (dir.dirName() == QLatin1String("debug") || dir.dirName() == QLatin1String("release")) { + dir.cdUp(); + } + dir.cdUp(); + dir.cdUp(); + dir.cdUp(); + QSize iconSize(128, 128); + QPixmap pix(iconSize); + QPainter painter(&pix); + QLinearGradient gradient(0,0, 0, iconSize.height()); + gradient.setColorAt(0.0, QColor(240, 240, 240)); + gradient.setColorAt(1.0, QColor(224, 224, 224)); + QBrush brush(gradient); + const QMetaObject &mo = QEasingCurve::staticMetaObject; + QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type")); + QFont oldFont = painter.font(); + // Skip QEasingCurve::Custom + QString output(QString::fromAscii("%1/images").arg(dir.absolutePath())); + printf("Generating images to %s\n", qPrintable(output)); + for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) { + painter.setFont(oldFont); + QString name(QLatin1String(metaEnum.key(i))); + painter.fillRect(QRect(QPoint(0, 0), iconSize), brush); + QEasingCurve curve((QEasingCurve::Type)i); + painter.setPen(QColor(0, 0, 255, 64)); + qreal xAxis = iconSize.height()/1.5; + qreal yAxis = iconSize.width()/3; + painter.drawLine(0, xAxis, iconSize.width(), xAxis); // hor + painter.drawLine(yAxis, 0, yAxis, iconSize.height()); // ver + + qreal curveScale = iconSize.height()/2; + + painter.drawLine(yAxis - 2, xAxis - curveScale, yAxis + 2, xAxis - curveScale); // hor + painter.drawLine(yAxis + curveScale, xAxis + 2, yAxis + curveScale, xAxis - 2); // ver + painter.drawText(yAxis + curveScale - 8, xAxis - curveScale - 4, QLatin1String("(1,1)")); + + painter.drawText(yAxis + 42, xAxis + 10, QLatin1String("progress")); + painter.drawText(15, xAxis - curveScale - 10, QLatin1String("ease")); + + painter.setPen(QPen(Qt::red, 1, Qt::DotLine)); + painter.drawLine(yAxis, xAxis - curveScale, yAxis + curveScale, xAxis - curveScale); // hor + painter.drawLine(yAxis + curveScale, xAxis, yAxis + curveScale, xAxis - curveScale); // ver + + QPoint currentPos(yAxis, xAxis); + + painter.setPen(Qt::black); + QFont font = oldFont; + font.setPixelSize(oldFont.pixelSize() + 15); + painter.setFont(font); + painter.drawText(0, iconSize.height() - 20, iconSize.width(), 20, Qt::AlignHCenter, name); + + for (qreal t = 0; t < 1.0; t+=1.0/curveScale) { + QPoint to; + to.setX(yAxis + curveScale * t); + to.setY(xAxis - curveScale * curve.valueForProgress(t)); + painter.drawLine(currentPos, to); + currentPos = to; + } + QString fileName(QString::fromAscii("qeasingcurve-%1.png").arg(name.toLower())); + printf("%s\n", qPrintable(fileName)); + pix.save(QString::fromAscii("%1/%2").arg(output).arg(fileName), "PNG"); + } +} + + diff --git a/doc/src/examples-overview.qdoc b/doc/src/examples-overview.qdoc index 549574d..92ccd4e 100644 --- a/doc/src/examples-overview.qdoc +++ b/doc/src/examples-overview.qdoc @@ -319,6 +319,14 @@ from displaying Web pages within a Qt user interface to an implementation of a basic function Web browser. + \section1 \l{Qt Examples#State Machine}{State Machine} + + Qt provides a powerful hierchical finite state machine through the Qt State + Machine classes. + + These examples demonstrate the fundamental aspects of implementing + Statecharts with Qt. + \section1 \l{Qt Examples#Qt for Embedded Linux}{Qt for Embedded Linux} \l{Qt Examples#Qt for Embedded Linux}{\inlineimage qt-embedded-examples.png diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index 29c6c0b..c55d29f 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -86,6 +86,12 @@ \o \l{activeqt/webbrowser}{Web Browser}\raisedaster \o \l{activeqt/wrapper}{Wrapper}\raisedaster \endlist + + \section1 Animation + + \list + \o \l{animation/stickman}{Stick man}\raisedaster + \endlist \section1 Concurrent Programming @@ -308,6 +314,17 @@ \o \l{sql/sqlwidgetmapper}{SQL Widget Mapper}\raisedaster \endlist + \section1 State Machine + + \list + \o \l{statemachine/eventtransitions}{Event Transitions}\raisedaster + \o \l{statemachine/factorial}{Factorial States}\raisedaster + \o \l{statemachine/pingpong}{Ping Pong States}\raisedaster + \o \l{statemachine/trafficlight}{Traffic Light}\raisedaster + \o \l{statemachine/twowaybutton}{Two-way Button}\raisedaster + \o \l{statemachine/tankgame}{Tank Game}\raisedaster + \endlist + \section1 Threads \list diff --git a/doc/src/examples/basicgraphicslayouts.qdoc b/doc/src/examples/basicgraphicslayouts.qdoc index 92571af..9696fb6 100644 --- a/doc/src/examples/basicgraphicslayouts.qdoc +++ b/doc/src/examples/basicgraphicslayouts.qdoc @@ -45,6 +45,7 @@ The Basic Graphics Layouts example shows how to use the layout classes in QGraphicsView: QGraphicsLinearLayout and QGraphicsGridLayout. + In addition to that it shows how to write your own custom layout item. \image basicgraphicslayouts-example.png Screenshot of the Basic Layouts Example @@ -115,26 +116,24 @@ \section1 LayoutItem Class Definition - The \c LayoutItem class is a subclass of QGraphicsWidget. It has a - constructor, a destructor, and a reimplementation of the - {QGraphicsItem::paint()}{paint()} function. + The \c LayoutItem class is a subclass of QGraphicsLayoutItem and + QGraphicsItem. It has a constructor, a destructor, and some required + reimplementations. + Since it inherits QGraphicsLayoutItem it must reimplement + {QGraphicsLayoutItem::setGeometry()}{setGeometry()} and + {QGraphicsLayoutItem::sizeHint()}{sizeHint()}. + In addition to that it inherits QGraphicsItem, so it must reimplement + {QGraphicsItem::boundingRect()}{boundingRect()} and + {QGraphicsItem::paint()}{paint()}. \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.h 0 - The \c LayoutItem class also has a private instance of QPixmap, \c pix. - - \note We subclass QGraphicsWidget so that \c LayoutItem objects can - be automatically plugged into a layout, as QGraphicsWidget is a - specialization of QGraphicsLayoutItem. + The \c LayoutItem class also has a private instance of QPixmap, \c m_pix. \section1 LayoutItem Class Implementation - In \c{LayoutItem}'s constructor, \c pix is instantiated and the - \c{QT_original_R.png} image is loaded into it. We set the size of - \c LayoutItem to be slightly larger than the size of the pixmap as we - require some space around it for borders that we will paint later. - Alternatively, you could scale the pixmap to prevent the item from - becoming smaller than the pixmap. + In \c{LayoutItem}'s constructor, \c m_pix is instantiated and the + \c{block.png} image is loaded into it. \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 0 @@ -148,4 +147,32 @@ \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 2 + The reimplementation of {QGraphicsItem::boundingRect()}{boundingRect()} + will set the top left corner at (0,0), and the size of it will be + the size of the layout items + {QGraphicsLayoutItem::geometry()}{geometry()}. This is the area that + we paint within. + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 3 + + + The reimplementation of {QGraphicsLayoutItem::setGeometry()}{setGeometry()} + simply calls its baseclass implementation. However, since this will change + the boundingRect we must also call + {QGraphicsItem::prepareGeometryChange()}{prepareGeometryChange()}. + Finally, we move the item according to \c geom.topLeft(). + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 4 + + + Since we don't want the size of the item to be smaller than the pixmap, we + must make sure that we return a size hint that is larger than \c m_pix. + We also add some extra space around for borders that we will paint later. + Alternatively, you could scale the pixmap to prevent the item from + becoming smaller than the pixmap. + The preferred size is the same as the minimum size hint, while we set + maximum to be a large value + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 5 + */
\ No newline at end of file diff --git a/doc/src/examples/contiguouscache.qdoc b/doc/src/examples/contiguouscache.qdoc new file mode 100644 index 0000000..fbfde3f --- /dev/null +++ b/doc/src/examples/contiguouscache.qdoc @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** 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 tools/contiguouscache + \title Contiguous Cache Example + + The Contiguous Cache example shows how to use QContiguousCache to manage memory usage for + very large models. In some environments memory is limited and, even when it + isn't, users still dislike an application using excessive memory. + Using QContiguousCache to manage a list, rather than loading + the entire list into memory, allows the application to limit the amount + of memory it uses, regardless of the size of the data set it accesses + + The simplest way to use QContiguousCache is to cache as items are requested. When + a view requests an item at row N it is also likely to ask for items at rows near + to N. + + \snippet examples/tools/contiguouscache/randomlistmodel.cpp 0 + + After getting the row, the class determines if the row is in the bounds + of the contiguous cache's current range. It would have been equally valid to + simply have the following code instead. + + \code + while (row > m_rows.lastIndex()) + m_rows.append(fetchWord(m_rows.lastIndex()+1); + while (row < m_rows.firstIndex()) + m_rows.prepend(fetchWord(m_rows.firstIndex()-1); + \endcode + + However a list will often jump rows if the scroll bar is used directly, resulting in + the code above causing every row between the old and new rows to be fetched. + + Using QContiguousCache::lastIndex() and QContiguousCache::firstIndex() allows + the example to determine what part of the list the cache is currently caching. + These values don't represent the indexes into the cache's own memory, but rather + a virtual infinite array that the cache represents. + + By using QContiguousCache::append() and QContiguousCache::prepend() the code ensures + that items that may be still on the screen are not lost when the requested row + has not moved far from the current cache range. QContiguousCache::insert() can + potentially remove more than one item from the cache as QContiguousCache does not + allow for gaps. If your cache needs to quickly jump back and forth between + rows with significant gaps between them consider using QCache instead. + + And thats it. A perfectly reasonable cache, using minimal memory for a very large + list. In this case the accessor for getting the words into the cache + generates random information rather than fixed information. This allows you + to see how the cache range is kept for a local number of rows when running the + example. + + \snippet examples/tools/contiguouscache/randomlistmodel.cpp 1 + + It is also worth considering pre-fetching items into the cache outside of the + application's paint routine. This can be done either with a separate thread + or using a QTimer to incrementally expand the range of the cache prior to + rows being requested out of the current cache range. +*/ diff --git a/doc/src/examples/eventtransitions.qdoc b/doc/src/examples/eventtransitions.qdoc new file mode 100644 index 0000000..3b956bb --- /dev/null +++ b/doc/src/examples/eventtransitions.qdoc @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 statemachine/eventtransitions + \title Event Transitions Example + + The Event Transitions example shows how to use event transitions, a + feature of \l{The State Machine Framework}. + + \snippet examples/statemachine/eventtransitions/main.cpp 0 + + The \c Window class's constructors begins by creating a button. + + \snippet examples/statemachine/eventtransitions/main.cpp 1 + + Two states, \c s1 and \c s2, are created; upon entry they will assign + "Outside" and "Inside" to the button's text, respectively. + + \snippet examples/statemachine/eventtransitions/main.cpp 2 + + When the button receives an event of type QEvent::Enter and the state + machine is in state \c s1, the machine will transition to state \c s2. + + \snippet examples/statemachine/eventtransitions/main.cpp 3 + + When the button receives an event of type QEvent::Leave and the state + machine is in state \c s2, the machine will transition back to state \c + s1. + + \snippet examples/statemachine/eventtransitions/main.cpp 4 + + Next, the state \c s3 is created. \c s3 will be entered when the button + receives an event of type QEvent::MouseButtonPress and the state machine + is in state \c s2. When the button receives an event of type + QEvent::MouseButtonRelease and the state machine is in state \c s3, the + machine will transition back to state \c s2. + + \snippet examples/statemachine/eventtransitions/main.cpp 5 + + Finally, the states are added to the machine as top-level states, the + initial state is set to be \c s1 ("Outside"), and the machine is started. + + \snippet examples/statemachine/eventtransitions/main.cpp 6 + + The main() function constructs a Window object and shows it. + +*/ diff --git a/doc/src/examples/factorial.qdoc b/doc/src/examples/factorial.qdoc new file mode 100644 index 0000000..2a72e0a --- /dev/null +++ b/doc/src/examples/factorial.qdoc @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** 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 statemachine/factorial + \title Factorial States Example + + The Factorial States example shows how to use \l{The State Machine + Framework} to calculate the factorial of an integer. + + The statechart for calculating the factorial looks as follows: + + \img factorial-example.png + \omit + \caption This is a caption + \endomit + + In other words, the state machine calculates the factorial of 6 and prints + the result. + + \snippet examples/statemachine/factorial/main.cpp 0 + + The Factorial class is used to hold the data of the computation, \c x and + \c fac. It also provides a signal that's emitted whenever the value of \c + x changes. + + \snippet examples/statemachine/factorial/main.cpp 1 + + The FactorialLoopTransition class implements the guard (\c x > 1) and + calculations (\c fac = \c x * \c fac; \c x = \c x - 1) of the factorial + loop. + + \snippet examples/statemachine/factorial/main.cpp 2 + + The FactorialDoneTransition class implements the guard (\c x <= 1) that + terminates the factorial computation. It also prints the final result to + standard output. + + \snippet examples/statemachine/factorial/main.cpp 3 + + The application's main() function first creates the application object, a + Factorial object and a state machine. + + \snippet examples/statemachine/factorial/main.cpp 4 + + The \c compute state is created, and the initial values of \c x and \c fac + are defined. A FactorialLoopTransition object is created and added to the + state. + + \snippet examples/statemachine/factorial/main.cpp 5 + + A final state, \c done, is created, and a FactorialDoneTransition object + is created with \c done as its target state. The transition is then added + to the \c compute state. + + \snippet examples/statemachine/factorial/main.cpp 6 + + The machine's initial state is set to be the \c compute state. We connect + the QStateMachine::finished() signal to the QCoreApplication::quit() slot, + so the application will quit when the state machine's work is + done. Finally, the state machine is started, and the application's event + loop is entered. + + */ diff --git a/doc/src/examples/pingpong.qdoc b/doc/src/examples/pingpong.qdoc new file mode 100644 index 0000000..040e429 --- /dev/null +++ b/doc/src/examples/pingpong.qdoc @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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 statemachine/pingpong + \title Ping Pong States Example + + The Ping Pong States example shows how to use parallel states together + with custom events and transitions in \l{The State Machine Framework}. + + This example implements a statechart where two states communicate by + posting events to the state machine. The state chart looks as follows: + + \img pingpong-example.png + \omit + \caption This is a caption + \endomit + + The \c pinger and \c ponger states are parallel states, i.e. they are + entered simultaneously and will take transitions independently of + eachother. + + The \c pinger state will post the first \c ping event upon entry; the \c + ponger state will respond by posting a \c pong event; this will cause the + \c pinger state to post a new \c ping event; and so on. + + \snippet examples/statemachine/pingpong/main.cpp 0 + + Two custom events are defined, \c PingEvent and \c PongEvent. + + \snippet examples/statemachine/pingpong/main.cpp 1 + + The \c Pinger class defines a state that posts a \c PingEvent to the state + machine when the state is entered. + + \snippet examples/statemachine/pingpong/main.cpp 2 + + The \c PingTransition class defines a transition that is triggered by + events of type \c PingEvent, and that posts a \c PongEvent (with a delay + of 500 milliseconds) to the state machine when the transition is + triggered. + + \snippet examples/statemachine/pingpong/main.cpp 3 + + The \c PongTransition class defines a transition that is triggered by + events of type \c PongEvent, and that posts a \c PingEvent (with a delay + of 500 milliseconds) to the state machine when the transition is + triggered. + + \snippet examples/statemachine/pingpong/main.cpp 4 + + The main() function begins by creating a state machine and a parallel + state group. + + \snippet examples/statemachine/pingpong/main.cpp 5 + + Next, the \c pinger and \c ponger states are created, with the parallel + state group as their parent state. Note that the transitions are \e + targetless. When such a transition is triggered, the source state won't be + exited and re-entered; only the transition's onTransition() function will + be called, and the state machine's configuration will remain the same, + which is precisely what we want in this case. + + \snippet examples/statemachine/pingpong/main.cpp 6 + + Finally, the group is added to the state machine, the machine is started, + and the application event loop is entered. + + */ diff --git a/doc/src/examples/stickman.qdoc b/doc/src/examples/stickman.qdoc new file mode 100644 index 0000000..49f4953 --- /dev/null +++ b/doc/src/examples/stickman.qdoc @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** 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 animation/stickman + \title Stickman Example + + The Stickman example shows how to animate transitions in a state machine to implement key frame + animations. + + \image stickman-example.png + + In this example, we will write a small application which animates the joints in a skeleton and + projects a stickman figure on top. The stickman can be either "alive" or "dead", and when in the + "alive" state, he can be performing different actions defined by key frame animations. + + Animations are implemented as composite states. Each child state of the animation state + represents a frame in the animation by setting the position of each joint in the stickman's + skeleton to the positions defined for the particular frame. The frames are then bound together + with animated transitions that trigger on the source state's polished() signal. Thus, the + machine will enter the state representing the next frame in the animation immediately after it + has finished animating into the previous frame. + + \image stickman-example1.png + + The states for an animation is constructed by reading a custom animation file format and + creating states that assign values to the the "position" properties of each of the nodes in the + skeleton graph. + + \snippet examples/animation/stickman/lifecycle.cpp 1 + + The states are then bound together with signal transitions that listen to the polished() signal. + + \snippet examples/animation/stickman/lifecycle.cpp 2 + + The last frame state is given a transition to the first one, so that the animation will loop + until it is interrupted when a transition out from the animation state is taken. To get smooth + animations between the different key frames, we set a default animation on the state machine. + This is a parallel animation group which contains animations for all the "position" properties + and will be selected by default when taking any transition that leads into a state that assigns + values to these properties. + + \snippet examples/animation/stickman/lifecycle.cpp 3 + + Several such animation states are constructed, and are placed together as children of a top + level "alive" state which represents the stickman life cycle. Transitions go from the parent + state to the child state to ensure that each of the child states inherit them. + + \image stickman-example2.png + + This saves us the effort of connect every state to every state with identical transitions. The + state machine makes sure that transitions between the key frame animations are also smooth by + applying the default animation when interrupting one and starting another. + + Finally, there is a transition out from the "alive" state and into the "dead" state. This is + a custom transition type called LightningSrikesTransition which samples every second and + triggers at random (one out of fifty times on average.) + + \snippet examples/animation/stickman/lifecycle.cpp 4 + + When it triggers, the machine will first enter a "lightningBlink" state which uses a timer to + pause for a brief period of time while the background color of the scene is white. This gives us + a flash effect when the lightning strikes. + + \snippet examples/animation/stickman/lifecycle.cpp 5 + + We start and stop a QTimer object when entering and exiting the state. Then we transition into + the "dead" state when the timer times out. + + \snippet examples/animation/stickman/lifecycle.cpp 0 + + When the machine is in the "dead" state, it will be unresponsive. This is because the "dead" + state has no transitions leading out. + + \image stickman-example3.png + +*/ diff --git a/doc/src/examples/tankgame.qdoc b/doc/src/examples/tankgame.qdoc new file mode 100644 index 0000000..ab3e0f4 --- /dev/null +++ b/doc/src/examples/tankgame.qdoc @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** 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 statemachine/tankgame + \title Tank Game Example + + The Tank Game example is part of the in \l{The State Machine Framework}. It shows how to use + parallel states to implement artificial intelligence controllers that run in parallel, and error + states to handle run-time errors in parts of the state graph created by external plugins. + + \image tankgame-example.png + + In this example we write a simple game. The application runs a state machine with two main + states: A "stopped" state and a "running" state. The user can load plugins from the disk by + selecting the "Add tank" menu item. + + When the "Add tank" menu item is selected, the "plugins" subdirectory in the example's + directory is searched for compatible plugins. If any are found, they will be listed in a + dialog box created using QInputDialog::getItem(). + + \snippet examples/statemachine/tankgame/mainwindow.cpp 1 + + If the user selects a plugin, the application will construct a TankItem object, which inherits + from QGraphicsItem and QObject, and which implements an agreed-upon interface using the + meta-object mechanism. + + \snippet examples/statemachine/tankgame/tankitem.h 0 + + The tank item will be passed to the plugin's create() function. This will in turn return a + QState object which is expected to implement an artificial intelligence which controls the + tank and attempts to destroy other tanks it detects. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 2 + + Each returned QState object becomes a descendant of a \c region in the "running" state, which is + defined as a parallel state. This means that entering the "running" state will cause each of the + plugged-in QState objects to be entered simultaneously, allowing the tanks to run independently + of each other. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 0 + + The maximum number of tanks on the map is four, and when this number is reached, the + "Add tank" menu item should be disabled. This is implemented by giving the "stopped" state two + children which define whether the map is full or not. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 5 + + To make sure that we go into the correct child state when returning from the "running" state + (if the "Stop game" menu item is selected while the game is running) we also give the "stopped" + state a history state which we make the initial state of "stopped" state. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 3 + + Since part of the state graph is defined by external plugins, we have no way of controlling + whether they contain errors. By default, run-time errors are handled in the state machine by + entering a top level state which prints out an error message and never exits. If we were to + use this default behavior, a run-time error in any of the plugins would cause the "running" + state to exit, and thus all the other tanks to stop running as well. A better solution would + be if the broken plugin was disabled and the rest of the tanks allowed to continue as before. + + This is done by setting the error state of the plugin's top-most state to a special error state + defined specifically for the plugin in question. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 4 + + If a run-time error occurs in \c pluginState or any of its descendants, the state machine will + search the hierarchy of ancestors until it finds a state whose error state is different from + \c null. (Note that if we are worried that a plugin could inadvertedly be overriding our + error state, we could search the descendants of \c pluginState and verify that their error + states are set to \c null before accepting the plugin.) + + The specialized \c errorState sets the "enabled" property of the tank item in question to false, + causing it to be painted with a red cross over it to indicate that it is no longer running. + Since the error state is a child of the same region in the parallel "running" state as + \c pluginState, it will not exit the "running" state, and the other tanks will continue running + without disruption. + +*/ diff --git a/doc/src/examples/trafficlight.qdoc b/doc/src/examples/trafficlight.qdoc new file mode 100644 index 0000000..ae62127 --- /dev/null +++ b/doc/src/examples/trafficlight.qdoc @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 statemachine/trafficlight + \title Traffic Light Example + + The Traffic Light example shows how to use \l{The State Machine Framework} + to implement the control flow of a traffic light. + + \image trafficlight-example.png + + In this example we write a TrafficLightWidget class. The traffic light has + three lights: Red, yellow and green. The traffic light transitions from + one light to another (red to yellow to green to yellow to red again) at + certain intervals. + + \snippet examples/statemachine/trafficlight/main.cpp 0 + + The LightWidget class represents a single light of the traffic light. It + provides an \c on property and two slots, turnOn() and turnOff(), to turn + the light on and off, respectively. The widget paints itself in the color + that's passed to the constructor. + + \snippet examples/statemachine/trafficlight/main.cpp 1 + + The TrafficLightWidget class represents the visual part of the traffic + light; it's a widget that contains three lights arranged vertically, and + provides accessor functions for these. + + \snippet examples/statemachine/trafficlight/main.cpp 2 + + The createLightState() function creates a state that turns a light on when + the state is entered, and off when the state is exited. The state uses a + timer, and as we shall see the timeout is used to transition from one + LightState to another. Here is the statechart for the light state: + + \img trafficlight-example1.png + \omit + \caption This is a caption + \endomit + + \snippet examples/statemachine/trafficlight/main.cpp 3 + + The TrafficLight class combines the TrafficLightWidget with a state + machine. The state graph has four states: red-to-yellow, yellow-to-green, + green-to-yellow and yellow-to-red. The initial state is red-to-yellow; + when the state's timer times out, the state machine transitions to + yellow-to-green. The same process repeats through the other states. + This is what the statechart looks like: + + \img trafficlight-example2.png + \omit + \caption This is a caption + \endomit + + \snippet examples/statemachine/trafficlight/main.cpp 4 + + The main() function constructs a TrafficLight and shows it. + +*/ diff --git a/doc/src/examples/twowaybutton.qdoc b/doc/src/examples/twowaybutton.qdoc new file mode 100644 index 0000000..87de2e8 --- /dev/null +++ b/doc/src/examples/twowaybutton.qdoc @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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 statemachine/twowaybutton + \title Two-way Button Example + + The Two-way button example shows how to use \l{The State Machine + Framework} to implement a simple state machine that toggles the current + state when a button is clicked. + + \snippet examples/statemachine/twowaybutton/main.cpp 0 + + The application's main() function begins by constructing the application + object, a button and a state machine. + + \snippet examples/statemachine/twowaybutton/main.cpp 1 + + The state machine has two states; \c on and \c off. When either state is + entered, the text of the button will be set accordingly. + + \snippet examples/statemachine/twowaybutton/main.cpp 2 + + When the state machine is in the \c off state and the button is clicked, + it will transition to the \c on state; when the state machine is in the \c + on state and the button is clicked, it will transition to the \c off + state. + + \snippet examples/statemachine/twowaybutton/main.cpp 3 + + The states are added to the state machine; they become top-level (sibling) + states. + + \snippet examples/statemachine/twowaybutton/main.cpp 4 + + The initial state is \c off; this is the state the state machine will + immediately transition to once the state machine is started. + + \snippet examples/statemachine/twowaybutton/main.cpp 5 + + Finally, the button is resized and made visible, and the application event + loop is entered. + +*/ diff --git a/doc/src/exportedfunctions.qdoc b/doc/src/exportedfunctions.qdoc index f67950c..f051ddc 100644 --- a/doc/src/exportedfunctions.qdoc +++ b/doc/src/exportedfunctions.qdoc @@ -129,6 +129,9 @@ on Mac OS X or be part of the main window. This feature is on by default. + In Qt 4.6, this is equivalent to + \c { QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar); }. + \section1 void qt_mac_set_press_and_hold_context(bool \e{enable}) Turns emulation of the right mouse button by clicking and holding diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index f48c3d7..3bfb5af 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -334,6 +334,16 @@ */ /*! + \externalpage http://www.w3.org/TR/scxml/ + \title State Chart XML: State Machine Notation for Control Abstraction +*/ + +/*! + \externalpage http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf + \title Statecharts: A visual formalism for complex systems +*/ + +/*! \externalpage http://www.gnu.org/licenses/gpl.html \title GNU General Public License */ diff --git a/doc/src/groups.qdoc b/doc/src/groups.qdoc index c9cedc4..3c4da53 100644 --- a/doc/src/groups.qdoc +++ b/doc/src/groups.qdoc @@ -69,6 +69,18 @@ */ /*! + \group animation + \ingroup groups + + \title Animation Framework + \brief Classes for animations, states and transitions. + + These classes provide a framework for creating both simple and complex + animations. \l{The Animation Framework} also provides states and animated + transitions, making it easy to create animated stateful forms. +*/ + +/*! \group abstractwidgets \title Abstract Widget Classes \ingroup groups @@ -597,3 +609,14 @@ These classes are relevant to developers who are working with Qt Script's debugging features. */ + +/*! + \group statemachine + \ingroup groups + + \title State Machine Classes + \brief Classes for constructing and executing state graphs. + + These classes are provided by \l{The State Machine Framework} for creating + event-driven state machines. +*/ diff --git a/doc/src/images/animations-architecture.png b/doc/src/images/animations-architecture.png Binary files differnew file mode 100644 index 0000000..9b581af --- /dev/null +++ b/doc/src/images/animations-architecture.png diff --git a/doc/src/images/factorial-example.png b/doc/src/images/factorial-example.png Binary files differnew file mode 100644 index 0000000..8fb1cc6 --- /dev/null +++ b/doc/src/images/factorial-example.png diff --git a/doc/src/images/pingpong-example.png b/doc/src/images/pingpong-example.png Binary files differnew file mode 100644 index 0000000..af707e4 --- /dev/null +++ b/doc/src/images/pingpong-example.png diff --git a/doc/src/images/qeasingcurve-cosinecurve.png b/doc/src/images/qeasingcurve-cosinecurve.png Binary files differnew file mode 100644 index 0000000..b27e763 --- /dev/null +++ b/doc/src/images/qeasingcurve-cosinecurve.png diff --git a/doc/src/images/qeasingcurve-inback.png b/doc/src/images/qeasingcurve-inback.png Binary files differnew file mode 100644 index 0000000..8506c0f --- /dev/null +++ b/doc/src/images/qeasingcurve-inback.png diff --git a/doc/src/images/qeasingcurve-inbounce.png b/doc/src/images/qeasingcurve-inbounce.png Binary files differnew file mode 100644 index 0000000..275b38c --- /dev/null +++ b/doc/src/images/qeasingcurve-inbounce.png diff --git a/doc/src/images/qeasingcurve-incirc.png b/doc/src/images/qeasingcurve-incirc.png Binary files differnew file mode 100644 index 0000000..b985e9c --- /dev/null +++ b/doc/src/images/qeasingcurve-incirc.png diff --git a/doc/src/images/qeasingcurve-incubic.png b/doc/src/images/qeasingcurve-incubic.png Binary files differnew file mode 100644 index 0000000..e417ee1 --- /dev/null +++ b/doc/src/images/qeasingcurve-incubic.png diff --git a/doc/src/images/qeasingcurve-incurve.png b/doc/src/images/qeasingcurve-incurve.png Binary files differnew file mode 100644 index 0000000..d9a9340 --- /dev/null +++ b/doc/src/images/qeasingcurve-incurve.png diff --git a/doc/src/images/qeasingcurve-inelastic.png b/doc/src/images/qeasingcurve-inelastic.png Binary files differnew file mode 100644 index 0000000..b242fd3 --- /dev/null +++ b/doc/src/images/qeasingcurve-inelastic.png diff --git a/doc/src/images/qeasingcurve-inexpo.png b/doc/src/images/qeasingcurve-inexpo.png Binary files differnew file mode 100644 index 0000000..f06316c --- /dev/null +++ b/doc/src/images/qeasingcurve-inexpo.png diff --git a/doc/src/images/qeasingcurve-inoutback.png b/doc/src/images/qeasingcurve-inoutback.png Binary files differnew file mode 100644 index 0000000..9fd1446 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutback.png diff --git a/doc/src/images/qeasingcurve-inoutbounce.png b/doc/src/images/qeasingcurve-inoutbounce.png Binary files differnew file mode 100644 index 0000000..fb65f31 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutbounce.png diff --git a/doc/src/images/qeasingcurve-inoutcirc.png b/doc/src/images/qeasingcurve-inoutcirc.png Binary files differnew file mode 100644 index 0000000..123cc54 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutcirc.png diff --git a/doc/src/images/qeasingcurve-inoutcubic.png b/doc/src/images/qeasingcurve-inoutcubic.png Binary files differnew file mode 100644 index 0000000..b07695c --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutcubic.png diff --git a/doc/src/images/qeasingcurve-inoutelastic.png b/doc/src/images/qeasingcurve-inoutelastic.png Binary files differnew file mode 100644 index 0000000..65851e1 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutelastic.png diff --git a/doc/src/images/qeasingcurve-inoutexpo.png b/doc/src/images/qeasingcurve-inoutexpo.png Binary files differnew file mode 100644 index 0000000..7cbfb13 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutexpo.png diff --git a/doc/src/images/qeasingcurve-inoutquad.png b/doc/src/images/qeasingcurve-inoutquad.png Binary files differnew file mode 100644 index 0000000..c5eed06 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutquad.png diff --git a/doc/src/images/qeasingcurve-inoutquart.png b/doc/src/images/qeasingcurve-inoutquart.png Binary files differnew file mode 100644 index 0000000..3b66c0d --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutquart.png diff --git a/doc/src/images/qeasingcurve-inoutquint.png b/doc/src/images/qeasingcurve-inoutquint.png Binary files differnew file mode 100644 index 0000000..c74efe9 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutquint.png diff --git a/doc/src/images/qeasingcurve-inoutsine.png b/doc/src/images/qeasingcurve-inoutsine.png Binary files differnew file mode 100644 index 0000000..5964f31 --- /dev/null +++ b/doc/src/images/qeasingcurve-inoutsine.png diff --git a/doc/src/images/qeasingcurve-inquad.png b/doc/src/images/qeasingcurve-inquad.png Binary files differnew file mode 100644 index 0000000..3373310 --- /dev/null +++ b/doc/src/images/qeasingcurve-inquad.png diff --git a/doc/src/images/qeasingcurve-inquart.png b/doc/src/images/qeasingcurve-inquart.png Binary files differnew file mode 100644 index 0000000..28086d8 --- /dev/null +++ b/doc/src/images/qeasingcurve-inquart.png diff --git a/doc/src/images/qeasingcurve-inquint.png b/doc/src/images/qeasingcurve-inquint.png Binary files differnew file mode 100644 index 0000000..330aa85 --- /dev/null +++ b/doc/src/images/qeasingcurve-inquint.png diff --git a/doc/src/images/qeasingcurve-insine.png b/doc/src/images/qeasingcurve-insine.png Binary files differnew file mode 100644 index 0000000..63d9238 --- /dev/null +++ b/doc/src/images/qeasingcurve-insine.png diff --git a/doc/src/images/qeasingcurve-linear.png b/doc/src/images/qeasingcurve-linear.png Binary files differnew file mode 100644 index 0000000..2a05885 --- /dev/null +++ b/doc/src/images/qeasingcurve-linear.png diff --git a/doc/src/images/qeasingcurve-outback.png b/doc/src/images/qeasingcurve-outback.png Binary files differnew file mode 100644 index 0000000..7cb34c6 --- /dev/null +++ b/doc/src/images/qeasingcurve-outback.png diff --git a/doc/src/images/qeasingcurve-outbounce.png b/doc/src/images/qeasingcurve-outbounce.png Binary files differnew file mode 100644 index 0000000..932fc16 --- /dev/null +++ b/doc/src/images/qeasingcurve-outbounce.png diff --git a/doc/src/images/qeasingcurve-outcirc.png b/doc/src/images/qeasingcurve-outcirc.png Binary files differnew file mode 100644 index 0000000..a1a6cb6 --- /dev/null +++ b/doc/src/images/qeasingcurve-outcirc.png diff --git a/doc/src/images/qeasingcurve-outcubic.png b/doc/src/images/qeasingcurve-outcubic.png Binary files differnew file mode 100644 index 0000000..aa1d604 --- /dev/null +++ b/doc/src/images/qeasingcurve-outcubic.png diff --git a/doc/src/images/qeasingcurve-outcurve.png b/doc/src/images/qeasingcurve-outcurve.png Binary files differnew file mode 100644 index 0000000..a949ae4 --- /dev/null +++ b/doc/src/images/qeasingcurve-outcurve.png diff --git a/doc/src/images/qeasingcurve-outelastic.png b/doc/src/images/qeasingcurve-outelastic.png Binary files differnew file mode 100644 index 0000000..2a9ba39 --- /dev/null +++ b/doc/src/images/qeasingcurve-outelastic.png diff --git a/doc/src/images/qeasingcurve-outexpo.png b/doc/src/images/qeasingcurve-outexpo.png Binary files differnew file mode 100644 index 0000000..e771c2e --- /dev/null +++ b/doc/src/images/qeasingcurve-outexpo.png diff --git a/doc/src/images/qeasingcurve-outinback.png b/doc/src/images/qeasingcurve-outinback.png Binary files differnew file mode 100644 index 0000000..7523727 --- /dev/null +++ b/doc/src/images/qeasingcurve-outinback.png diff --git a/doc/src/images/qeasingcurve-outinbounce.png b/doc/src/images/qeasingcurve-outinbounce.png Binary files differnew file mode 100644 index 0000000..ab73d02 --- /dev/null +++ b/doc/src/images/qeasingcurve-outinbounce.png diff --git a/doc/src/images/qeasingcurve-outincirc.png b/doc/src/images/qeasingcurve-outincirc.png Binary files differnew file mode 100644 index 0000000..ec4b8d3 --- /dev/null +++ b/doc/src/images/qeasingcurve-outincirc.png diff --git a/doc/src/images/qeasingcurve-outincubic.png b/doc/src/images/qeasingcurve-outincubic.png Binary files differnew file mode 100644 index 0000000..8b8ae68 --- /dev/null +++ b/doc/src/images/qeasingcurve-outincubic.png diff --git a/doc/src/images/qeasingcurve-outinelastic.png b/doc/src/images/qeasingcurve-outinelastic.png Binary files differnew file mode 100644 index 0000000..89dde2c --- /dev/null +++ b/doc/src/images/qeasingcurve-outinelastic.png diff --git a/doc/src/images/qeasingcurve-outinexpo.png b/doc/src/images/qeasingcurve-outinexpo.png Binary files differnew file mode 100644 index 0000000..5909901 --- /dev/null +++ b/doc/src/images/qeasingcurve-outinexpo.png diff --git a/doc/src/images/qeasingcurve-outinquad.png b/doc/src/images/qeasingcurve-outinquad.png Binary files differnew file mode 100644 index 0000000..7ddefee --- /dev/null +++ b/doc/src/images/qeasingcurve-outinquad.png diff --git a/doc/src/images/qeasingcurve-outinquart.png b/doc/src/images/qeasingcurve-outinquart.png Binary files differnew file mode 100644 index 0000000..00ef597 --- /dev/null +++ b/doc/src/images/qeasingcurve-outinquart.png diff --git a/doc/src/images/qeasingcurve-outinquint.png b/doc/src/images/qeasingcurve-outinquint.png Binary files differnew file mode 100644 index 0000000..361bfaa4 --- /dev/null +++ b/doc/src/images/qeasingcurve-outinquint.png diff --git a/doc/src/images/qeasingcurve-outinsine.png b/doc/src/images/qeasingcurve-outinsine.png Binary files differnew file mode 100644 index 0000000..1737041 --- /dev/null +++ b/doc/src/images/qeasingcurve-outinsine.png diff --git a/doc/src/images/qeasingcurve-outquad.png b/doc/src/images/qeasingcurve-outquad.png Binary files differnew file mode 100644 index 0000000..6f27cbd --- /dev/null +++ b/doc/src/images/qeasingcurve-outquad.png diff --git a/doc/src/images/qeasingcurve-outquart.png b/doc/src/images/qeasingcurve-outquart.png Binary files differnew file mode 100644 index 0000000..d45a0b8 --- /dev/null +++ b/doc/src/images/qeasingcurve-outquart.png diff --git a/doc/src/images/qeasingcurve-outquint.png b/doc/src/images/qeasingcurve-outquint.png Binary files differnew file mode 100644 index 0000000..6e7df0e --- /dev/null +++ b/doc/src/images/qeasingcurve-outquint.png diff --git a/doc/src/images/qeasingcurve-outsine.png b/doc/src/images/qeasingcurve-outsine.png Binary files differnew file mode 100644 index 0000000..7546a0d --- /dev/null +++ b/doc/src/images/qeasingcurve-outsine.png diff --git a/doc/src/images/qeasingcurve-sinecurve.png b/doc/src/images/qeasingcurve-sinecurve.png Binary files differnew file mode 100644 index 0000000..ca67d44 --- /dev/null +++ b/doc/src/images/qeasingcurve-sinecurve.png diff --git a/doc/src/images/statemachine-button-history.png b/doc/src/images/statemachine-button-history.png Binary files differnew file mode 100644 index 0000000..7f51cae --- /dev/null +++ b/doc/src/images/statemachine-button-history.png diff --git a/doc/src/images/statemachine-button-nested.png b/doc/src/images/statemachine-button-nested.png Binary files differnew file mode 100644 index 0000000..762ac14 --- /dev/null +++ b/doc/src/images/statemachine-button-nested.png diff --git a/doc/src/images/statemachine-button.png b/doc/src/images/statemachine-button.png Binary files differnew file mode 100644 index 0000000..10102bd --- /dev/null +++ b/doc/src/images/statemachine-button.png diff --git a/doc/src/images/statemachine-customevents.png b/doc/src/images/statemachine-customevents.png Binary files differnew file mode 100644 index 0000000..62a4222 --- /dev/null +++ b/doc/src/images/statemachine-customevents.png diff --git a/doc/src/images/statemachine-customevents2.png b/doc/src/images/statemachine-customevents2.png Binary files differnew file mode 100644 index 0000000..57b37ef --- /dev/null +++ b/doc/src/images/statemachine-customevents2.png diff --git a/doc/src/images/statemachine-finished.png b/doc/src/images/statemachine-finished.png Binary files differnew file mode 100644 index 0000000..0ac081d --- /dev/null +++ b/doc/src/images/statemachine-finished.png diff --git a/doc/src/images/statemachine-nonparallel.png b/doc/src/images/statemachine-nonparallel.png Binary files differnew file mode 100644 index 0000000..f9850a7 --- /dev/null +++ b/doc/src/images/statemachine-nonparallel.png diff --git a/doc/src/images/statemachine-parallel.png b/doc/src/images/statemachine-parallel.png Binary files differnew file mode 100644 index 0000000..a65c297 --- /dev/null +++ b/doc/src/images/statemachine-parallel.png diff --git a/doc/src/images/stickman-example.png b/doc/src/images/stickman-example.png Binary files differnew file mode 100644 index 0000000..a40f37b --- /dev/null +++ b/doc/src/images/stickman-example.png diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png Binary files differnew file mode 100644 index 0000000..1596a68 --- /dev/null +++ b/doc/src/images/stickman-example1.png diff --git a/doc/src/images/stickman-example2.png b/doc/src/images/stickman-example2.png Binary files differnew file mode 100644 index 0000000..980276a --- /dev/null +++ b/doc/src/images/stickman-example2.png diff --git a/doc/src/images/stickman-example3.png b/doc/src/images/stickman-example3.png Binary files differnew file mode 100644 index 0000000..3635ff7 --- /dev/null +++ b/doc/src/images/stickman-example3.png diff --git a/doc/src/images/tankgame-example.png b/doc/src/images/tankgame-example.png Binary files differnew file mode 100644 index 0000000..9e17e30 --- /dev/null +++ b/doc/src/images/tankgame-example.png diff --git a/doc/src/images/trafficlight-example.png b/doc/src/images/trafficlight-example.png Binary files differnew file mode 100644 index 0000000..3431542 --- /dev/null +++ b/doc/src/images/trafficlight-example.png diff --git a/doc/src/images/trafficlight-example1.png b/doc/src/images/trafficlight-example1.png Binary files differnew file mode 100644 index 0000000..ec8c7ff --- /dev/null +++ b/doc/src/images/trafficlight-example1.png diff --git a/doc/src/images/trafficlight-example2.png b/doc/src/images/trafficlight-example2.png Binary files differnew file mode 100644 index 0000000..a12e4db --- /dev/null +++ b/doc/src/images/trafficlight-example2.png diff --git a/doc/src/phonon-api.qdoc b/doc/src/phonon-api.qdoc index dd37fe2..5deb64e 100644 --- a/doc/src/phonon-api.qdoc +++ b/doc/src/phonon-api.qdoc @@ -1032,6 +1032,7 @@ \value Stream The MediaSource object describes a data stream. This is the type used for \l{QIODevice}s. Note that a stream opened with a QUrl, will still be of the Url type. + \value Empty The media source doesn't have a source. \sa MediaSource::type() */ @@ -2026,6 +2027,15 @@ */ /*! + \fn void Phonon::MediaObject::clear() + + Stops and removes all playing and enqueued media sources. + + \sa setCurrentSource() +*/ + + +/*! \fn void Phonon::MediaObject::stateChanged(Phonon::State newstate, Phonon::State oldstate) This signal is emitted when the state of the MediaObject has changed. @@ -3027,6 +3037,12 @@ */ /*! + \typedef Phonon::AudioOutputInterface + \inmodule Phonon + \internal +*/ + +/*! \class Phonon::AudioOutputInterface40 \inmodule Phonon \since 4.4 @@ -3251,7 +3267,19 @@ /*! \fn bool Phonon::Path::operator!=(const Path &p) const; - Returns true if this Path is not equal to \a p; otherwise returns false; + Returns true if this Path is not equal to \a p; otherwise returns false. +*/ + +/*! + \fn MediaNode *Phonon::Path::source() const; + + Returns the source MediaNode used by the path. +*/ + +/*! + \fn MediaNode *Phonon::Path::sink() const; + + Returns the sink MediaNode used by the path. */ /*! @@ -4878,7 +4906,7 @@ */ /*! - \typedef typedef void (*CleanUpFunction)() + \typedef Phonon::CleanUpFunction \inmodule Phonon \internal */ diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index d9f001e..069541f 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -129,13 +129,8 @@ Therefore, if it is important to minimize resource consumption, do not set this attribute. - \value AA_MSWindowsUseDirect3DByDefault Is a Windows specific - attribute, that will make the Direct3D paint engine the - default Qt widget paint engine. Note that you can toggle - usage of the Direct3D engine on individual QWidgets by - setting/clearing the \c WA_MSWindowsUseDirect3D attribute - on a specific widget. \bold {This functionality is - experimental}. + \value AA_MSWindowsUseDirect3DByDefault This value is obsolete and + has no effect. \value AA_DontShowIconsInMenus Actions with the Icon property won't be shown in any menus unless specifically set by the @@ -151,10 +146,24 @@ widgets stay non-native unless specifically set by the Qt::WA_NativeWindow attribute. - \value AA_MacPluginApplication Stops the a Qt mac application from doing + \value AA_MacPluginApplication Stops the Qt mac application from doing specific initializations that do not necessarily make sense when using Qt to author a plugin. This includes avoiding loading our nib for the main - menu and not taking possession of the native menu bar. + menu and not taking possession of the native menu bar. When setting this + attribute to true will also set the AA_DontUseNativeMenuBar attribute + to true. + + \value AA_DontUseNativeMenuBar All menubars created while this attribute is + set to true won't be used as a native menubar (e.g, the menubar at + the top of the main screen on Mac OS X or at the bottom in Windows CE). + + \value AA_MacDontSwapCtrlAndMeta On Mac OS X by default, Qt swaps the + Control and Meta (Command) keys (i.e., whenever Control is pressed, Qt + sends Meta and whenever Meta is pressed Control is sent. When this + attribute is true, Qt will not do the flip. QKeySequence::StandardShortcuts + will also flip accordingly (i.e., QKeySequence::Copy will be + Command+C on the keyboard regardless of the value set, though what is output for + QKeySequence::toString(QKeySequence::PortableText) will be different). \omitvalue AA_AttributeCount */ @@ -519,6 +528,10 @@ Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection. + \value UniqueConnection Same as AutoConnection, but there will be a check that the signal is + not already connected to the same slot before connecting, otherwise, + the connection will fail. + \since 4.6 With queued connections, the parameters must be of types that are known to Qt's meta-object system, because Qt needs to copy the arguments to store them @@ -948,10 +961,8 @@ position. This is set/cleared by QWidget::move() and by QWidget::setGeometry(). - \value WA_MSWindowsUseDirect3D Makes drawing to a widget - with this attribute set use the Direct3D paint engine, if the - Direct3D paint engine is available. \bold {This functionality - is experimental.} + \value WA_MSWindowsUseDirect3D This value is obsolete and has no + effect. \value WA_NoBackground This value is obsolete. Use WA_OpaquePaintEvent instead. @@ -2658,3 +2669,16 @@ \sa QGraphicsWidget::windowFrameSectionAt() */ + +/*! + \enum Qt::TileRule + \since 4.6 + + This enum describes how to repeat or stretch the parts of an image when drawing. + + \value Stretch Scale the image to fit to the available area. + \value Repeat Tile the image until there is no more space. May crop the last image. + \value Round Like Repeat, but scales the images down to ensure that the last image is not cropped. + + \sa QPixmapBorders, qDrawBorderPixmap() +*/ diff --git a/doc/src/qset.qdoc b/doc/src/qset.qdoc index 6326219..a168800 100644 --- a/doc/src/qset.qdoc +++ b/doc/src/qset.qdoc @@ -324,6 +324,16 @@ \sa insert(), remove(), find() */ +/*! + \fn bool QSet::contains(const QSet<T> &other) const + \since 4.6 + + Returns true if the set contains all items from the \a other set; + otherwise returns false. + + \sa insert(), remove(), find() +*/ + /*! \fn QSet::const_iterator QSet::begin() const Returns a const \l{STL-style iterator} positioned at the first diff --git a/doc/src/signalsandslots.qdoc b/doc/src/signalsandslots.qdoc index 5432bd4..29c8215 100644 --- a/doc/src/signalsandslots.qdoc +++ b/doc/src/signalsandslots.qdoc @@ -178,9 +178,13 @@ looping in the case of cyclic connections (e.g., if \c{b.valueChanged()} were connected to \c{a.setValue()}). - A signal is emitted for every connection you make; if you - duplicate a connection, two signals will be emitted. You can - always break a connection using QObject::disconnect(). + By default, for every connection you make, a signal is emitted; + two signals are emitted for duplicate connections. You can break + all of these connections with a single disconnect() call. + If you pass the Qt::UniqueConnection \a type, the connection will only + be made if it is not a duplicate. If there is already a duplicate + (exact same signal to the exact same slot on the same objects), + the connection will fail and connect will return false This example illustrates that objects can work together without needing to know any information about each other. To enable this, the objects only @@ -218,8 +222,8 @@ will continue immediately, and the slots will be executed later. If several slots are connected to one signal, the slots will be - executed one after the other, in an arbitrary order, when the signal - is emitted. + executed one after the other, in the order they have been connected, + when the signal is emitted. Signals are automatically generated by the \l moc and must not be implemented in the \c .cpp file. They can never have return types diff --git a/doc/src/snippets/animation/sequential/icons.qrc b/doc/src/snippets/animation/sequential/icons.qrc new file mode 100644 index 0000000..d55f797 --- /dev/null +++ b/doc/src/snippets/animation/sequential/icons.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> + <qresource> + <file>icons/left.png</file> + <file>icons/right.png</file> + </qresource> +</RCC> diff --git a/doc/src/snippets/animation/sequential/icons/left.png b/doc/src/snippets/animation/sequential/icons/left.png Binary files differnew file mode 100644 index 0000000..5dd8da0 --- /dev/null +++ b/doc/src/snippets/animation/sequential/icons/left.png diff --git a/doc/src/snippets/animation/sequential/icons/right.png b/doc/src/snippets/animation/sequential/icons/right.png Binary files differnew file mode 100644 index 0000000..ac61326 --- /dev/null +++ b/doc/src/snippets/animation/sequential/icons/right.png diff --git a/doc/src/snippets/animation/sequential/main.cpp b/doc/src/snippets/animation/sequential/main.cpp new file mode 100644 index 0000000..aff8f29 --- /dev/null +++ b/doc/src/snippets/animation/sequential/main.cpp @@ -0,0 +1,50 @@ +#include <QApplication> +#include <QLabel> +#include <QPropertyAnimation> +#include <QSequentialAnimationGroup> +#include "tracer.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QWidget window; + window.resize(720, 96); + window.show(); + + QLabel *label1 = new QLabel(&window); + label1->setPixmap(QPixmap(":/icons/left.png")); + label1->move(16, 16); + label1->show(); + + QLabel *label2 = new QLabel(&window); + label2->setPixmap(QPixmap(":/icons/right.png")); + label2->move(320, 16); + label2->show(); + + QPropertyAnimation *anim1 = new QPropertyAnimation(label1, "pos"); + anim1->setDuration(2500); + anim1->setStartValue(QPoint(16, 16)); + anim1->setEndValue(QPoint(320, 16)); + + QPropertyAnimation *anim2 = new QPropertyAnimation(label2, "pos"); + anim2->setDuration(2500); + anim2->setStartValue(QPoint(320, 16)); + anim2->setEndValue(QPoint(640, 16)); + + QSequentialAnimationGroup group; + group.addAnimation(anim1); + group.addAnimation(anim2); + + Tracer tracer(&window); + + QObject::connect(anim1, SIGNAL(valueChanged(QVariant)), + &tracer, SLOT(recordValue(QVariant))); + QObject::connect(anim2, SIGNAL(valueChanged(QVariant)), + &tracer, SLOT(recordValue(QVariant))); + QObject::connect(anim1, SIGNAL(finished()), &tracer, SLOT(checkValue())); + QObject::connect(anim2, SIGNAL(finished()), &tracer, SLOT(checkValue())); + + group.start(); + return app.exec(); +} diff --git a/doc/src/snippets/animation/sequential/sequential.pro b/doc/src/snippets/animation/sequential/sequential.pro new file mode 100644 index 0000000..fcf017f --- /dev/null +++ b/doc/src/snippets/animation/sequential/sequential.pro @@ -0,0 +1,4 @@ +HEADERS = tracer.h +RESOURCES = icons.qrc +SOURCES = main.cpp \ + tracer.cpp diff --git a/doc/src/snippets/animation/sequential/tracer.cpp b/doc/src/snippets/animation/sequential/tracer.cpp new file mode 100644 index 0000000..49bd51e --- /dev/null +++ b/doc/src/snippets/animation/sequential/tracer.cpp @@ -0,0 +1,25 @@ +#include <QAbstractAnimation> +#include <QDebug> +#include <QPoint> +#include "tracer.h" + +Tracer::Tracer(QObject *parent) + : QObject(parent) +{ +} + +void Tracer::checkValue() +{ + QAbstractAnimation *animation = static_cast<QAbstractAnimation *>(sender()); + if (time != animation->duration()) { + qDebug() << "Animation's last recorded time" << time; + qDebug() << "Expected" << animation->duration(); + } +} + +void Tracer::recordValue(const QVariant &value) +{ + QAbstractAnimation *animation = static_cast<QAbstractAnimation *>(sender()); + this->value = value; + time = animation->currentTime(); +} diff --git a/doc/src/snippets/animation/sequential/tracer.h b/doc/src/snippets/animation/sequential/tracer.h new file mode 100644 index 0000000..1adb018 --- /dev/null +++ b/doc/src/snippets/animation/sequential/tracer.h @@ -0,0 +1,23 @@ +#ifndef TRACER_H +#define TRACER_H + +#include <QObject> +#include <QVariant> + +class Tracer : public QObject +{ + Q_OBJECT + +public: + Tracer(QObject *parent = 0); + +public slots: + void checkValue(); + void recordValue(const QVariant &value); + +private: + QVariant value; + int time; +}; + +#endif diff --git a/doc/src/snippets/code/doc_src_stylesheet.qdoc b/doc/src/snippets/code/doc_src_stylesheet.qdoc index 60622d3..a62148f 100644 --- a/doc/src/snippets/code/doc_src_stylesheet.qdoc +++ b/doc/src/snippets/code/doc_src_stylesheet.qdoc @@ -1538,6 +1538,11 @@ QSplitter::handle:horizontal { QSplitter::handle:vertical { height: 2px; } + +QSplitter::handle:pressed { + url(images/splitter_pressed.png); +} + //! [142] diff --git a/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp new file mode 100644 index 0000000..65358ea --- /dev/null +++ b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp @@ -0,0 +1,4 @@ +//! [0] +qreal myEasingFunction(qreal progress); +//! [0] + diff --git a/doc/src/snippets/code/src_gui_image_qpixmap.cpp b/doc/src/snippets/code/src_gui_image_qpixmap.cpp index f86eeae..822b466 100644 --- a/doc/src/snippets/code/src_gui_image_qpixmap.cpp +++ b/doc/src/snippets/code/src_gui_image_qpixmap.cpp @@ -10,3 +10,9 @@ static const char * const start_xpm[]={ QPixmap myPixmap; myPixmap->setMask(myPixmap->createHeuristicMask()); //! [1] + +//! [2] +QPixmap pixmap("background.png"); +QRegion exposed; +pixmap.scroll(10, 10, pixmap.rect(), &exposed); +//! [2] diff --git a/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp b/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp index c4b6353..2a04f64 100644 --- a/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp +++ b/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp @@ -13,7 +13,7 @@ painter->drawPixmap(0, 0, p); //! [1] QPixmap pm; -if (!QPixmapCache::find("my_big_image", pm)) { +if (!QPixmapCache::find("my_big_image", &pm)) { pm.load("bigimage.png"); QPixmapCache::insert("my_big_image", pm); } diff --git a/doc/src/snippets/qprocess-environment/main.cpp b/doc/src/snippets/qprocess-environment/main.cpp index bce3578..148518b 100644 --- a/doc/src/snippets/qprocess-environment/main.cpp +++ b/doc/src/snippets/qprocess-environment/main.cpp @@ -43,6 +43,7 @@ void startProcess() { + { //! [0] QProcess process; QStringList env = QProcess::systemEnvironment(); @@ -51,6 +52,18 @@ env.replaceInStrings(QRegExp("^PATH=(.*)", Qt::CaseInsensitive), "PATH=\\1;C:\\B process.setEnvironment(env); process.start("myapp"); //! [0] + } + + { +//! [1] +QProcess process; +QHash<QString, QString> env = QProcess::systemEnvironmentHash(); +env.insert("TMPDIR", "C:\\MyApp\\temp"); // Add an environment variable +env["PATH"] += ";C:\\Bin"; +process.setEnvironment(env); +process.start("myapp"); +//! [0] + } } int main(int argc, char *argv[]) diff --git a/doc/src/snippets/widgets-tutorial/template.cpp b/doc/src/snippets/widgets-tutorial/template.cpp new file mode 100644 index 0000000..5958676 --- /dev/null +++ b/doc/src/snippets/widgets-tutorial/template.cpp @@ -0,0 +1,14 @@ +#include <QtGui> + +// Include header files for application components. +// ... + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + // Set up and show widgets. + // ... + + return app.exec(); +} diff --git a/doc/src/statemachine.qdoc b/doc/src/statemachine.qdoc new file mode 100644 index 0000000..5a89f4d --- /dev/null +++ b/doc/src/statemachine.qdoc @@ -0,0 +1,645 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \page statemachine-api.html + \title The State Machine Framework + \brief An overview of the State Machine framework for constructing and executing state graphs. + \ingroup architecture + + \tableofcontents + + The State Machine framework provides classes for creating and executing + state graphs. The concepts and notation are based on those from Harel's + \l{Statecharts: A visual formalism for complex systems}{Statecharts}, which + is also the basis of UML state diagrams. The semantics of state machine + execution are based on \l{State Chart XML: State Machine Notation for + Control Abstraction}{State Chart XML (SCXML)}. + + Statecharts provide a graphical way of modeling how a system reacts to + stimuli. This is done by defining the possible \e states that the system can + be in, and how the system can move from one state to another (\e transitions + between states). A key characteristic of event-driven systems (such as Qt + applications) is that behavior often depends not only on the last or current + event, but also the events that preceded it. With statecharts, this + information is easy to express. + + The State Machine framework provides an API and execution model that can be + used to effectively embed the elements and semantics of statecharts in Qt + applications. The framework integrates tightly with Qt's meta-object system; + for example, transitions between states can be triggered by signals, and + states can be configured to set properties and invoke methods on QObjects. + Qt's event system is used to drive the state machines. + + \section1 A Simple State Machine + + To demonstrate the core functionality of the State Machine API, let's look + at a small example: A state machine with three states, \c s1, \c s2 and \c + s3. The state machine is controlled by a single QPushButton; when the button + is clicked, the machine transitions to another state. Initially, the state + machine is in state \c s1. The statechart for this machine is as follows: + + \img statemachine-button.png + \omit + \caption This is a caption + \endomit + + The following snippet shows the code needed to create such a state machine. + First, we create the state machine and states: + + \code + QStateMachine machine; + QState *s1 = new QState(); + QState *s2 = new QState(); + QState *s3 = new QState(); + \endcode + + Then, we create the transitions by using the QState::addTransition() + function: + + \code + s1->addTransition(button, SIGNAL(clicked()), s2); + s2->addTransition(button, SIGNAL(clicked()), s3); + s3->addTransition(button, SIGNAL(clicked()), s1); + \endcode + + Next, we add the states to the machine and set the machine's initial state: + + \code + machine.addState(s1); + machine.addState(s2); + machine.addState(s3); + machine.setInitialState(s1); + \endcode + + Finally, we start the state machine: + + \code + machine.start(); + \endcode + + The state machine executes asynchronously, i.e. it becomes part of your + application's event loop. + + \section1 Doing Useful Work on State Entry and Exit + + The above state machine merely transitions from one state to another, it + doesn't perform any operations. The QState::assignProperty() function can be + used to have a state set a property of a QObject when the state is + entered. In the following snippet, the value that should be assigned to a + QLabel's text property is specified for each state: + + \code + s1->assignProperty(label, "text", "In state s1"); + s2->assignProperty(label, "text", "In state s2"); + s3->assignProperty(label, "text", "In state s3"); + \endcode + + When any of the states is entered, the label's text will be changed + accordingly. + + The QState::entered() signal is emitted when the state is entered, and the + QState::exited() signal is emitted when the state is exited. In the + following snippet, the button's showMaximized() slot will be called when + state \c s3 is entered, and the button's showMinimized() slot will be called + when \c s3 is exited: + + \code + QObject::connect(s3, SIGNAL(entered()), button, SLOT(showMaximized())); + QObject::connect(s3, SIGNAL(exited()), button, SLOT(showMinimized())); + \endcode + + Custom states can reimplement QAbstractState::onEntry() and + QAbstractState::onExit(). + + \section1 State Machines That Finish + + The state machine defined in the previous section never finishes. In order + for a state machine to be able to finish, it needs to have a top-level \e + final state (QFinalState object). When the state machine enters a top-level + final state, the machine will emit the QStateMachine::finished() signal and + halt. + + All you need to do to introduce a final state in the graph is create a + QFinalState object and use it as the target of one or more transitions. + + \section1 Sharing Transitions By Grouping States + + Assume we wanted the user to be able to quit the application at any time by + clicking a Quit button. In order to achieve this, we need to create a final + state and make it the target of a transition associated with the Quit + button's clicked() signal. We could add a transition from each of \c s1, \c + s2 and \c s3; however, this seems redundant, and one would also have to + remember to add such a transition from every new state that is added in the + future. + + We can achieve the same behavior (namely that clicking the Quit button quits + the state machine, regardless of which state the state machine is in) by + grouping states \c s1, \c s2 and \c s3. This is done by creating a new + top-level state and making the three original states children of the new + state. The following diagram shows the new state machine. + + \img statemachine-button-nested.png + \omit + \caption This is a caption + \endomit + + The three original states have been renamed \c s11, \c s12 and \c s13 to + reflect that they are now children of the new top-level state, \c s1. Child + states implicitly inherit the transitions of their parent state. This means + it is now sufficient to add a single transition from \c s1 to the final + state \c s2. New states added to \c s1 will also automatically inherit this + transition. + + All that's needed to group states is to specify the proper parent when the + state is created. You also need to specify which of the child states is the + initial one (i.e. which child state the state machine should enter when the + parent state is the target of a transition). + + \code + QState *s1 = new QState(); + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); + QState *s13 = new QState(s1); + s1->setInitialState(s11); + machine.addState(s1); + \endcode + + \code + QFinalState *s2 = new QFinalState(); + s1->addTransition(quitButton, SIGNAL(clicked()), s2); + machine.addState(s2); + + QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); + \endcode + + In this case we want the application to quit when the state machine is + finished, so the machine's finished() signal is connected to the + application's quit() slot. + + A child state can override an inherited transition. For example, the + following code adds a transition that effectively causes the Quit button to + be ignored when the state machine is in state \c s12. + + \code + s12>addTransition(quitButton, SIGNAL(clicked()), s12); + \endcode + + A transition can have any state as its target, i.e. the target state does + not have to be on the same level in the state hierarchy as the source state. + + \section1 Using History States to Save and Restore the Current State + + Imagine that we wanted to add an "interrupt" mechanism to the example + discussed in the previous section; the user should be able to click a button + to have the state machine perform some non-related task, after which the + state machine should resume whatever it was doing before (i.e. return to the + old state, which is one of \c s11, \c s12 and \c s13 in this case). + + Such behavior can easily be modeled using \e{history states}. A history + state (QHistoryState object) is a pseudo-state that represents the child + state that the parent state was in the last time the parent state was + exited. + + A history state is created as a child of the state for which we wish to + record the current child state; when the state machine detects the presence + of such a state at runtime, it automatically records the current (real) + child state when the parent state is exited. A transition to the history + state is in fact a transition to the child state that the state machine had + previously saved; the state machine automatically "forwards" the transition + to the real child state. + + The following diagram shows the state machine after the interrupt mechanism + has been added. + + \img statemachine-button-history.png + \omit + \caption This is a caption + \endomit + + The following code shows how it can be implemented; in this example we + simply display a message box when \c s3 is entered, then immediately return + to the previous child state of \c s1 via the history state. + + \code + QHistoryState *s1h = s1->addHistoryState(); + + QState *s3 = new QState(); + s3->assignProperty(label, "text", "In s3"); + QMessageBox mbox; + mbox.addButton(QMessageBox::Ok); + mbox.setText("Interrupted!"); + mbox.setIcon(QMessageBox::Information); + QObject::connect(s3, SIGNAL(entered()), &mbox, SLOT(exec())); + s3->addTransition(s1h); + machine.addState(s3); + + s1->addTransition(interruptButton, SIGNAL(clicked()), s3); + \endcode + + \section1 Using Parallel States to Avoid a Combinatorial Explosion of States + + Assume that you wanted to model a set of mutually exclusive properties of a + car in a single state machine. Let's say the properties we are interested in + are Clean vs Dirty, and Moving vs Not moving. It would take four mutually + exclusive states and eight transitions to be able to represent and freely + move between all possible combinations. + + \img statemachine-nonparallel.png + \omit + \caption This is a caption + \endomit + + If we added a third property (say, Red vs Blue), the total number of states + would double, to eight; and if we added a fourth property (say, Enclosed vs + Convertible), the total number of states would double again, to 16. + + Using parallel states, the total number of states and transitions grows + linearly as we add more properties, instead of exponentially. Furthermore, + states can be added to or removed from the parallel state without affecting + any of their sibling states. + + \img statemachine-parallel.png + \omit + \caption This is a caption + \endomit + + To create a parallel state group, pass QState::ParallelStates to the QState + constructor. + + \code + QState *s1 = new QState(QState::ParallelStates); + // s11 and s12 will be entered in parallel + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); + \endcode + + When a parallel state group is entered, all its child states will be + simultaneously entered. Transitions within the individual child states + operate normally. However, any of the child states may take a transition + outside the parent state. When this happens, the parent state and all of its + child states are exited. + + \section1 Detecting that a Composite State has Finished + + A child state can be final (a QFinalState object); when a final child state + is entered, the parent state emits the QState::finished() signal. The + following diagram shows a composite state \c s1 which does some processing + before entering a final state: + + \img statemachine-finished.png + \omit + \caption This is a caption + \endomit + + When \c s1 's final state is entered, \c s1 will automatically emit + finished(). We use a signal transition to cause this event to trigger a + state change: + + \code + s1->addTransition(s1, SIGNAL(finished()), s2); + \endcode + + Using final states in composite states is useful when you want to hide the + internal details of a composite state; i.e. the only thing the outside world + should be able to do is enter the state, and get a notification when the + state has completed its work. This is a very powerful abstraction and + encapsulation mechanism when building complex (deeply nested) state + machines. (In the above example, you could of course create a transition + directly from \c s1 's \c done state rather than relying on \c s1 's + finished() signal, but with the consequence that implementation details of + \c s1 are exposed and depended on). + + For parallel state groups, the QState::finished() signal is emitted when \e + all the child states have entered final states. + + \section1 Events, Transitions and Guards + + A QStateMachine runs its own event loop. For signal transitions + (QSignalTransition objects), QStateMachine automatically posts a + QSignalEvent to itself when it intercepts the corresponding signal; + similarly, for QObject event transitions (QEventTransition objects) a + QWrappedEvent is posted. + + You can post your own events to the state machine using + QStateMachine::postEvent(). + + When posting a custom event to the state machine, you typically also have + one or more custom transitions that can be triggered from events of that + type. To create such a transition, you subclass QAbstractTransition and + reimplement QAbstractTransition::eventTest(), where you check if an event + matches your event type (and optionally other criteria, e.g. attributes of + the event object). + + Here we define our own custom event type, \c StringEvent, for posting + strings to the state machine: + + \code + struct StringEvent : public QEvent + { + StringEvent(const QString &val) + : QEvent(QEvent::Type(QEvent::User+1)), + value(val) {} + + QString value; + }; + \endcode + + Next, we define a transition that only triggers when the event's string + matches a particular string (a \e guarded transition): + + \code + class StringTransition : public QAbstractTransition + { + public: + StringTransition(const QString &value) + : m_value(value) {} + + protected: + virtual bool eventTest(QEvent *e) const + { + if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent + return false; + StringEvent *se = static_cast<StringEvent*>(e); + return (m_value == se->value); + } + + virtual void onTransition(QEvent *) {} + + private: + QString m_value; + }; + \endcode + + In the eventTest() reimplementation, we first check if the event type is the + desired one; if so, we cast the event to a StringEvent and perform the + string comparison. + + The following is a statechart that uses the custom event and transition: + + \img statemachine-customevents.png + \omit + \caption This is a caption + \endomit + + Here's what the implementation of the statechart looks like: + + \code + QStateMachine machine; + QState *s1 = new QState(); + QState *s2 = new QState(); + QFinalState *done = new QFinalState(); + + StringTransition *t1 = new StringTransition("Hello"); + t1->setTargetState(s2); + s1->addTransition(t1); + StringTransition *t2 = new StringTransition("world"); + t2->setTargetState(done); + s2->addTransition(t2); + + machine.addState(s1); + machine.addState(s2); + machine.addState(done); + machine.setInitialState(s1); + \endcode + + Once the machine is started, we can post events to it. + + \code + machine.postEvent(new StringEvent("Hello")); + machine.postEvent(new StringEvent("world")); + \endcode + + An event that is not handled by any relevant transition will be silently + consumed by the state machine. It can be useful to group states and provide + a default handling of such events; for example, as illustrated in the + following statechart: + + \img statemachine-customevents2.png + \omit + \caption This is a caption + \endomit + + For deeply nested statecharts, you can add such "fallback" transitions at + the level of granularity that's most appropriate. + + \section1 Using Restore Policy To Automatically Restore Properties + + In some state machines it can be useful to focus the attention on assigning properties in states, + not on restoring them when the state is no longer active. If you know that a property should + always be restored to its initial value when the machine enters a state that does not explicitly + give the property a value, you can set the global restore policy to + QStateMachine::RestoreProperties. + + \code + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + \endcode + + When this restore policy is set, the machine will automatically restore all properties. If it + enters a state where a given property is not set, it will first search the hierarchy of ancestors + to see if the property is defined there. If it is, the property will be restored to the value + defined by the closest ancestor. If not, it will be restored to its initial value (i.e. the + value of the property before any property assignments in states were executed.) + + Take the following code: + \code + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QState *s1 = new QState(); + s1->assignProperty(object, "fooBar", 1.0); + machine.addState(s1); + machine.setInitialState(s1); + + QState *s2 = new QState(); + machine.addState(s2); + \endcode + + Lets say the property \c fooBar is 0.0 when the machine starts. When the machine is in state + \c s1, the property will be 1.0, since the state explicitly assigns this value to it. When the + machine is in state \c s2, no value is explicitly defined for the property, so it will implicitly + be restored to 0.0. + + If we are using nested states, the parent defines a value for the property which is inherited by + all descendants that do not explicitly assign a value to the property. + \code + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QState *s1 = new QState(); + s1->assignProperty(object, "fooBar", 1.0); + machine.addState(s1); + machine.setInitialState(s1); + + QState *s2 = new QState(s1); + s2->assignProperty(object, "fooBar", 2.0); + s1->setInitialState(s2); + + QState *s3 = new QState(s1); + \endcode + + Here \c s1 has two children: \c s2 and \c s3. When \c s2 is entered, the property \c fooBar + will have the value 2.0, since this is explicitly defined for the state. When the machine is in + state \c s3, no value is defined for the state, but \c s1 defines the property to be 1.0, so this + is the value that will be assigned to \c fooBar. + + \section1 Animating Property Assignments + + The State Machine API connects with the Animation API in Qt to allow automatically animating + properties as they are assigned in states. + + Say we have the following code: + \code + QState *s1 = new QState(); + QState *s2 = new QState(); + + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); + + s1->addTransition(button, SIGNAL(clicked()), s2); + \endcode + + Here we define two states of a user interface. In \c s1 the \c button is small, and in \c s2 + it is bigger. If we click the button to transition from \c s1 to \c s2, the geometry of the button + will be set immediately when a given state has been entered. If we want the transition to be + smooth, however, all we need to do is make a QPropertyAnimation and add this to the transition + object. + + \code + QState *s1 = new QState(); + QState *s2 = new QState(); + + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); + + QSignalTransition *transition = s1->addTransition(button, SIGNAL(clicked()), s2); + transition->addAnimation(new QPropertyAnimation(button, "geometry")); + \endcode + + Adding an animation for the property in question means that the property assignment will no + longer take immediate effect when the state has been entered. Instead, the animation will start + playing when the state has been entered and smoothly animate the property assignment. Since we + do not set the start value or end value of the animation, these will be set implicitly. The + start value of the animation will be the property's current value when the animation starts, and + the end value will be set based on the property assignments defined for the state. + + If the global restore policy of the state machine is set to QStateMachine::RestoreProperties, + it is possible to also add animations for the property restorations. + + \section1 Detecting That All Properties Have Been Set In A State + + When animations are used to assign properties, a state no longer defines the exact values that a + property will have when the machine is in the given state. While the animation is running, the + property can potentially have any value, depending on the animation. + + In some cases, it can be useful to be able to detect when the property has actually been assigned + the value defined by a state. For this, we can use the state's polished() signal. + \code + QState *s1 = new QState(); + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + + QState *s2 = new QState(); + + s1->addTransition(s1, SIGNAL(polished()), s2); + \endcode + + The machine will be in state \c s1 until the \c geometry property has been set. Then it will + immediately transition into \c s2. If the transition into \c s1 has an animation for the \c + geometry property, then the machine will stay in \c s1 until the animation has finished. If there + is no animation, it will simply set the property and immediately enter state \c s2. + + Either way, when the machine is in state \c s2, the property \c geometry has been assigned the + defined value. + + If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit + the polished() signal until these have been executed as well. + + \section1 What happens if a state is exited before the animation has finished + + If a state has property assignments, and the transition into the state has animations for the + properties, the state can potentially be exited before the properties have been assigned to the + values defines by the state. This is true in particular when there are transitions out from the + state that do not depend on the state being polished, as described in the previous section. + + The State Machine API guarantees that a property assigned by the state machine either: + \list + \o Has a value explicitly assigned to the property. + \o Is currently being animated into a value explicitly assigned to the property. + \endlist + + When a state is exited prior to the animation finishing, the behavior of the state machine depends + on the target state of the transition. If the target state explicitly assigns a value to the + property, no additional action will be taken. The property will be assigned the value defined by + the target state. + + If the target state does not assign any value to the property, there are two + options: By default, the property will be assigned the value defined by the state it is leaving + (the value it would have been assigned if the animation had been permitted to finish playing.) If + a global restore policy is set, however, this will take precedence, and the property will be + restored as usual. + + \section1 Default Animations + + As described earlier, you can add animations to transitions to make sure property assignments + in the target state are animated. If you want a specific animation to be used for a given property + regardless of which transition is taken, you can add it as a default animation to the state + machine. This is in particular useful when the properties assigned (or restored) by specific + states is not known when the machine is constructed. + + \code + QState *s1 = new QState(); + QState *s2 = new QState(); + + s2->assignProperty(object, "fooBar", 2.0); + s1->addTransition(s2); + + QStateMachine machine; + machine.setInitialState(s1); + machine.addDefaultAnimation(new QPropertyAnimation(object, "fooBar")); + \endcode + + When the machine is in state \c s2, the machine will play the default animation for the + property \c fooBar since this property is assigned by \c s2. + + Note that animations explicitly set on transitions will take precedence over any default + animation for the given property. +*/ diff --git a/doc/src/tutorials/addressbook-fr.qdoc b/doc/src/tutorials/addressbook-fr.qdoc index 2847f1b..512a404 100644 --- a/doc/src/tutorials/addressbook-fr.qdoc +++ b/doc/src/tutorials/addressbook-fr.qdoc @@ -239,13 +239,16 @@ \snippet tutorials/addressbook/part1/main.cpp main function - On construit un nouveau widget \c AddressBook sur le tas en utilisant le mot-clé - \c new et en invoquant sa méthode \l{QWidget::show()}{show()} pour l'afficher. + On construit un nouveau widget \c AddressBook sur la pile et on invoque + sa méthode \l{QWidget::show()}{show()} pour l'afficher. Cependant, le widget ne sera pas visible tant que la boucle d'évènements n'aura pas été lancée. On démarre la boucle d'évènements en appelant la méthode \l{QApplication::}{exec()} de l'application; le résultat renvoyé par cette méthode est lui même utilisé comme valeur de retour pour la méthode \c main(). + On comprend maintenant pourquoi \c AddressBook a été créé sur la pile: à la fin + du programme, l'objet sort du scope de la fonction \c main() et tous ses widgets enfants + sont supprimés, assurant ainsi qu'il n'y aura pas de fuites de mémoire. */ /*! diff --git a/doc/src/tutorials/addressbook.qdoc b/doc/src/tutorials/addressbook.qdoc index 3b0d2bc..38200b0 100644 --- a/doc/src/tutorials/addressbook.qdoc +++ b/doc/src/tutorials/addressbook.qdoc @@ -242,12 +242,15 @@ \snippet tutorials/addressbook/part1/main.cpp main function - We construct a new \c AddressBook widget on the heap using the \c new - keyword and invoke its \l{QWidget::show()}{show()} function to display it. + We construct a new \c AddressBook widget on the stack and invoke + its \l{QWidget::show()}{show()} function to display it. However, the widget will not be shown until the application's event loop is started. We start the event loop by calling the application's \l{QApplication::}{exec()} function; the result returned by this function - is used as the return value from the \c main() function. + is used as the return value from the \c main() function. At this point, + it becomes apparent why we instanciated \c AddressBook on the stack: It + will now go out of scope. Therefore, \c AddressBook and all its child widgets + will be deleted, thus preventing memory leaks. */ /*! diff --git a/doc/src/tutorials/widgets-tutorial.qdoc b/doc/src/tutorials/widgets-tutorial.qdoc index ead44af..1e89431 100644 --- a/doc/src/tutorials/widgets-tutorial.qdoc +++ b/doc/src/tutorials/widgets-tutorial.qdoc @@ -41,11 +41,14 @@ /*! \page widgets-tutorial.html + \startpage {index.html}{Qt Reference Documentation} + \nextpage {tutorials/widgets/toplevel}{Creating a Window} \title Widgets Tutorial \ingroup tutorials - \brief This tutorial covers basic usage of widgets and layouts, showing how they are used to build GUI applications. + \brief This tutorial covers basic usage of widgets and layouts, showing how + they are used to build GUI applications. \section1 Introduction @@ -68,7 +71,60 @@ occupied by its parent. This means that, when a window is deleted, all the widgets it contains are automatically deleted. - \section1 Creating a Window + \section1 Writing a main Function + + Many of the GUI examples in Qt follow the pattern of having a \c{main.cpp} + file containing code to initialize the application, and a number of other + source and header files containing the application logic and custom GUI + components. + + A typical \c main() function, written in \c{main.cpp}, looks like this: + + \quotefile doc/src/snippets/widgets-tutorial/template.cpp + + We first construct a QApplication object which is configured using any + arguments passed in from the command line. After any widgets have been + created and shown, we call QApplication::exec() to start Qt's event loop. + Control passes to Qt until this function returns, at which point we return + the value we obtain from this function. + + In each part of this tutorial, we provide an example that is written + entirely within a \c main() function. In more sophisticated examples, the + code to set up widgets and layouts is written in other parts of the + example. For example, the GUI for a main window may be set up in the + constructor of a QMainWindow subclass. + + The \l{Qt Examples#Widgets}{Widgets examples} are a good place to look for + more complex and complete examples and applications. + + \section1 Building Examples and Tutorials + + If you obtained a binary package of Qt or compiled it yourself, the + examples described in this tutorial should already be ready to run. + However, if you may wish to modify them and recompile them, you need to + perform the following steps: + + \list 1 + \o At the command line, enter the directory containing the example you + wish to recompile. + \o Type \c qmake and press \key{Return}. If this doesn't work, make sure + that the executable is on your path, or enter its full location. + \o On Linux/Unix and Mac OS X, type \c make and press \key{Return}; + on Windows with Visual Studio, type \c nmake and press \key{Return}. + \endlist + + An executable file should have been created within the current directory. + On Windows, this file may be located within a \c debug or \c release + subdirectory. You can run this file to see the example code at work. +*/ + +/*! + \page widgets-tutorial-toplevel.html + \contentspage {Widgets Tutorial}{Contents} + \previouspage {Widgets Tutorial} + \nextpage {Widgets Tutorial - Child Widgets} + \example tutorials/widgets/toplevel + \title Widgets Tutorial - Creating a Window If a widget is created without a parent, it is treated as a window, or \e{top-level widget}, when it is shown. Since it has no parent object to @@ -82,7 +138,7 @@ <table align="left" width="100%"> <tr class="qt-code"><td> \endraw - \snippet snippets/widgets-tutorial/toplevel/main.cpp create, resize and show + \snippet tutorials/widgets/toplevel/main.cpp main program \raw HTML </td><td align="right"> \endraw @@ -92,15 +148,28 @@ </table> \endraw - We can add a child widget to this window by passing \c window as the - parent to its constructor. In this case, we add a button to the window - and place it in a specific location: + To create a real GUI, we need to place widgets inside the window. To do + this, we pass a QWidget instance to a widget's constructor, as we will + demonstrate in the next part of this tutorial. +*/ + +/*! + \page widgets-tutorial-childwidget.html + \contentspage {Widgets Tutorial}{Contents} + \previouspage {Widgets Tutorial - Creating a Window} + \nextpage {Widgets Tutorial - Using Layouts} + \example tutorials/widgets/childwidget + \title Widgets Tutorial - Child Widgets + + We can add a child widget to the window created in the previous example by + passing \c window as the parent to its constructor. In this case, we add a + button to the window and place it in a specific location: \raw HTML <table align="left" width="100%"> <tr class="qt-code"><td> \endraw - \snippet snippets/widgets-tutorial/childwidget/main.cpp create, position and show + \snippet tutorials/widgets/childwidget/main.cpp main program \raw HTML </td><td align="right"> \endraw @@ -112,9 +181,16 @@ The button is now a child of the window and will be deleted when the window is destroyed. Note that hiding or closing the window does not - automatically destroy it. + automatically destroy it. It will be destroyed when the example exits. +*/ - \section1 Using Layouts +/*! + \page widgets-tutorial-windowlayout.html + \contentspage {Widgets Tutorial}{Contents} + \previouspage {Widgets Tutorial - Child Widgets} + \nextpage {Widgets Tutorial - Nested Layouts} + \example tutorials/widgets/windowlayout + \title Widgets Tutorial - Using Layouts Usually, child widgets are arranged inside a window using layout objects rather than by specifying positions and sizes explicitly. Here, we @@ -125,7 +201,7 @@ <table align="left" width="100%"> <tr class="qt-code"><td> \endraw - \snippet snippets/widgets-tutorial/windowlayout/main.cpp create, lay out widgets and show + \snippet tutorials/widgets/windowlayout/main.cpp main program \raw HTML </td><td align="right"> \endraw @@ -149,17 +225,31 @@ manage the label and line edit and set the layout on the window, both the widgets and the layout itself are ''reparented'' to become children of the window. +*/ + +/*! + \page widgets-tutorial-nestedlayouts.html + \contentspage {Widgets Tutorial}{Contents} + \previouspage {Widgets Tutorial - Using Layouts} + \example tutorials/widgets/nestedlayouts + \title Widgets Tutorial - Nested Layouts Just as widgets can contain other widgets, layouts can be used to provide different levels of grouping for widgets. Here, we want to display a label alongside a line edit at the top of a window, above a table view showing the results of a query. + We achieve this by creating two layouts: \c{queryLayout} is a QHBoxLayout + that contains QLabel and QLineEdit widgets placed side-by-side; + \c{mainLayout} is a QVBoxLayout that contains \c{queryLayout} and a + QTableView arranged vertically. + \raw HTML <table align="left" width="100%"> <tr class="qt-code"><td> \endraw - \snippet snippets/widgets-tutorial/nestedlayouts/main.cpp create, lay out widgets and show + \snippet tutorials/widgets/nestedlayouts/main.cpp first part + \snippet tutorials/widgets/nestedlayouts/main.cpp last part \raw HTML </td><td align="right"> \endraw @@ -169,6 +259,26 @@ </table> \endraw + Note that we call the \c{mainLayout}'s \l{QBoxLayout::}{addLayout()} + function to insert the \c{queryLayout} above the \c{resultView} table. + + We have omitted the code that sets up the model containing the data shown + by the QTableView widget, \c resultView. For completeness, we show this below. + As well as QHBoxLayout and QVBoxLayout, Qt also provides QGridLayout and QFormLayout classes to help with more complex user interfaces. + These can be seen if you run \l{Qt Designer}. + + \section1 Setting up the Model + + In the code above, we did not show where the table's data came from + because we wanted to concentrate on the use of layouts. Here, we see + that the model holds a number of items corresponding to rows, each of + which is set up to contain data for two columns. + + \snippet tutorials/widgets/nestedlayouts/main.cpp set up the model + + The use of models and views is covered in the + \l{Qt Examples#Item Views}{item view examples} and in the + \l{Model/View Programming} overview. */ |