diff options
Diffstat (limited to 'examples/statemachine')
-rw-r--r-- | examples/statemachine/README | 36 | ||||
-rw-r--r-- | examples/statemachine/eventtransitions/eventtransitions.pro | 7 | ||||
-rw-r--r-- | examples/statemachine/eventtransitions/main.cpp | 110 | ||||
-rw-r--r-- | examples/statemachine/factorial/factorial.pro | 11 | ||||
-rw-r--r-- | examples/statemachine/factorial/main.cpp | 175 | ||||
-rw-r--r-- | examples/statemachine/pingpong/main.cpp | 139 | ||||
-rw-r--r-- | examples/statemachine/pingpong/pingpong.pro | 11 | ||||
-rw-r--r-- | examples/statemachine/rogue/main.cpp | 54 | ||||
-rw-r--r-- | examples/statemachine/rogue/movementtransition.h | 107 | ||||
-rw-r--r-- | examples/statemachine/rogue/rogue.pro | 11 | ||||
-rw-r--r-- | examples/statemachine/rogue/window.cpp | 200 | ||||
-rw-r--r-- | examples/statemachine/rogue/window.h | 90 | ||||
-rw-r--r-- | examples/statemachine/statemachine.pro | 18 | ||||
-rw-r--r-- | examples/statemachine/trafficlight/main.cpp | 184 | ||||
-rw-r--r-- | examples/statemachine/trafficlight/trafficlight.pro | 7 | ||||
-rw-r--r-- | examples/statemachine/twowaybutton/main.cpp | 81 | ||||
-rw-r--r-- | examples/statemachine/twowaybutton/twowaybutton.pro | 7 |
17 files changed, 1248 insertions, 0 deletions
diff --git a/examples/statemachine/README b/examples/statemachine/README new file mode 100644 index 0000000000..2879e67d65 --- /dev/null +++ b/examples/statemachine/README @@ -0,0 +1,36 @@ +Qt is provided with a powerful hierchical finite state machine through +the Qt State Machine classes. + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. diff --git a/examples/statemachine/eventtransitions/eventtransitions.pro b/examples/statemachine/eventtransitions/eventtransitions.pro new file mode 100644 index 0000000000..646c90a07d --- /dev/null +++ b/examples/statemachine/eventtransitions/eventtransitions.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/eventtransitions +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS eventtransitions.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/eventtransitions +INSTALLS += target sources diff --git a/examples/statemachine/eventtransitions/main.cpp b/examples/statemachine/eventtransitions/main.cpp new file mode 100644 index 0000000000..5391057992 --- /dev/null +++ b/examples/statemachine/eventtransitions/main.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +//! [0] +class Window : public QWidget +{ +public: + Window(QWidget *parent = 0) + : QWidget(parent) + { + QPushButton *button = new QPushButton(this); + button->setGeometry(QRect(100, 100, 100, 100)); +//! [0] + +//! [1] + QStateMachine *machine = new QStateMachine(this); + + QState *s1 = new QState(); + s1->assignProperty(button, "text", "Outside"); + + QState *s2 = new QState(); + s2->assignProperty(button, "text", "Inside"); +//! [1] + +//! [2] + QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter); + enterTransition->setTargetState(s2); + s1->addTransition(enterTransition); +//! [2] + +//! [3] + QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave); + leaveTransition->setTargetState(s1); + s2->addTransition(leaveTransition); +//! [3] + +//! [4] + QState *s3 = new QState(); + s3->assignProperty(button, "text", "Pressing..."); + + QEventTransition *pressTransition = new QEventTransition(button, QEvent::MouseButtonPress); + pressTransition->setTargetState(s3); + s2->addTransition(pressTransition); + + QEventTransition *releaseTransition = new QEventTransition(button, QEvent::MouseButtonRelease); + releaseTransition->setTargetState(s2); + s3->addTransition(releaseTransition); +//! [4] + +//! [5] + machine->addState(s1); + machine->addState(s2); + machine->addState(s3); + + machine->setInitialState(s1); + machine->start(); + } +}; +//! [5] + +//! [6] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window window; + window.resize(300, 300); + window.show(); + + return app.exec(); +} +//! [6] diff --git a/examples/statemachine/factorial/factorial.pro b/examples/statemachine/factorial/factorial.pro new file mode 100644 index 0000000000..4291d43306 --- /dev/null +++ b/examples/statemachine/factorial/factorial.pro @@ -0,0 +1,11 @@ +QT = core +win32: CONFIG += console +mac:CONFIG -= app_bundle + +SOURCES += main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/factorial +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS factorial.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/factorial +INSTALLS += target sources diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp new file mode 100644 index 0000000000..15e1306e24 --- /dev/null +++ b/examples/statemachine/factorial/main.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <stdio.h> + +//! [0] +class Factorial : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x READ x WRITE setX) + Q_PROPERTY(int fac READ fac WRITE setFac) +public: + Factorial(QObject *parent = 0) + : QObject(parent), m_x(-1), m_fac(1) + { + } + + int x() const + { + return m_x; + } + + void setX(int x) + { + if (x == m_x) + return; + m_x = x; + emit xChanged(x); + } + + int fac() const + { + return m_fac; + } + + void setFac(int fac) + { + m_fac = fac; + } + +Q_SIGNALS: + void xChanged(int value); + +private: + int m_x; + int m_fac; +}; +//! [0] + +//! [1] +class FactorialLoopTransition : public QSignalTransition +{ +public: + FactorialLoopTransition(Factorial *fact) + : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) + {} + + virtual bool eventTest(QEvent *e) + { + if (!QSignalTransition::eventTest(e)) + return false; + QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e); + return se->arguments().at(0).toInt() > 1; + } + + virtual void onTransition(QEvent *e) + { + QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e); + int x = se->arguments().at(0).toInt(); + int fac = m_fact->property("fac").toInt(); + m_fact->setProperty("fac", x * fac); + m_fact->setProperty("x", x - 1); + } + +private: + Factorial *m_fact; +}; +//! [1] + +//! [2] +class FactorialDoneTransition : public QSignalTransition +{ +public: + FactorialDoneTransition(Factorial *fact) + : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) + {} + + virtual bool eventTest(QEvent *e) + { + if (!QSignalTransition::eventTest(e)) + return false; + QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e); + return se->arguments().at(0).toInt() <= 1; + } + + virtual void onTransition(QEvent *) + { + fprintf(stdout, "%d\n", m_fact->property("fac").toInt()); + } + +private: + Factorial *m_fact; +}; +//! [2] + +//! [3] +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + Factorial factorial; + QStateMachine machine; +//! [3] + +//! [4] + QState *compute = new QState(&machine); + compute->assignProperty(&factorial, "fac", 1); + compute->assignProperty(&factorial, "x", 6); + compute->addTransition(new FactorialLoopTransition(&factorial)); +//! [4] + +//! [5] + QFinalState *done = new QFinalState(&machine); + FactorialDoneTransition *doneTransition = new FactorialDoneTransition(&factorial); + doneTransition->setTargetState(done); + compute->addTransition(doneTransition); +//! [5] + +//! [6] + machine.setInitialState(compute); + QObject::connect(&machine, SIGNAL(finished()), &app, SLOT(quit())); + machine.start(); + + return app.exec(); +} +//! [6] + +#include "main.moc" diff --git a/examples/statemachine/pingpong/main.cpp b/examples/statemachine/pingpong/main.cpp new file mode 100644 index 0000000000..330824d3e8 --- /dev/null +++ b/examples/statemachine/pingpong/main.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <stdio.h> + +//! [0] +class PingEvent : public QEvent +{ +public: + PingEvent() : QEvent(QEvent::Type(QEvent::User+2)) + {} +}; + +class PongEvent : public QEvent +{ +public: + PongEvent() : QEvent(QEvent::Type(QEvent::User+3)) + {} +}; +//! [0] + +//! [1] +class Pinger : public QState +{ +public: + Pinger(QState *parent) + : QState(parent) {} + +protected: + virtual void onEntry(QEvent *) + { + machine()->postEvent(new PingEvent()); + fprintf(stdout, "ping?\n"); + } +}; +//! [1] + +//! [3] +class PongTransition : public QAbstractTransition +{ +public: + PongTransition() {} + +protected: + virtual bool eventTest(QEvent *e) { + return (e->type() == QEvent::User+3); + } + virtual void onTransition(QEvent *) + { + machine()->postDelayedEvent(new PingEvent(), 500); + fprintf(stdout, "ping?\n"); + } +}; +//! [3] + +//! [2] +class PingTransition : public QAbstractTransition +{ +public: + PingTransition() {} + +protected: + virtual bool eventTest(QEvent *e) { + return (e->type() == QEvent::User+2); + } + virtual void onTransition(QEvent *) + { + machine()->postDelayedEvent(new PongEvent(), 500); + fprintf(stdout, "pong!\n"); + } +}; +//! [2] + +//! [4] +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + QStateMachine machine; + QState *group = new QState(QState::ParallelStates); + group->setObjectName("group"); +//! [4] + +//! [5] + Pinger *pinger = new Pinger(group); + pinger->setObjectName("pinger"); + pinger->addTransition(new PongTransition()); + + QState *ponger = new QState(group); + ponger->setObjectName("ponger"); + ponger->addTransition(new PingTransition()); +//! [5] + +//! [6] + machine.addState(group); + machine.setInitialState(group); + machine.start(); + + return app.exec(); +} +//! [6] diff --git a/examples/statemachine/pingpong/pingpong.pro b/examples/statemachine/pingpong/pingpong.pro new file mode 100644 index 0000000000..9d2b17fc9e --- /dev/null +++ b/examples/statemachine/pingpong/pingpong.pro @@ -0,0 +1,11 @@ +QT = core +win32: CONFIG += console +mac:CONFIG -= app_bundle + +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/pingpong +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS pingpong.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/pingpong +INSTALLS += target sources diff --git a/examples/statemachine/rogue/main.cpp b/examples/statemachine/rogue/main.cpp new file mode 100644 index 0000000000..71c2c69470 --- /dev/null +++ b/examples/statemachine/rogue/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "window.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + + Window window; + window.show(); + + return app.exec(); +} + diff --git a/examples/statemachine/rogue/movementtransition.h b/examples/statemachine/rogue/movementtransition.h new file mode 100644 index 0000000000..1153b7508d --- /dev/null +++ b/examples/statemachine/rogue/movementtransition.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOVEMENTTRANSITION_H +#define MOVEMENTTRANSITION_H + +#include <QtGui> + +#include "window.h" + +//![0] +class MovementTransition : public QEventTransition +{ + Q_OBJECT + +public: + MovementTransition(Window *window) : + QEventTransition(window, QEvent::KeyPress) { + this->window = window; + } +//![0] + +//![1] +protected: + bool eventTest(QEvent *event) { + if (event->type() == QEvent::StateMachineWrapped && + static_cast<QStateMachine::WrappedEvent *>(event)->event()->type() == QEvent::KeyPress) { + QEvent *wrappedEvent = static_cast<QStateMachine::WrappedEvent *>(event)->event(); + + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(wrappedEvent); + int key = keyEvent->key(); + + return key == Qt::Key_2 || key == Qt::Key_8 || key == Qt::Key_6 || + key == Qt::Key_4; + } + return false; + } +//![1] + +//![2] + void onTransition(QEvent *event) { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>( + static_cast<QStateMachine::WrappedEvent *>(event)->event()); + + int key = keyEvent->key(); + switch (key) { + case Qt::Key_4: + window->movePlayer(Window::Left); + break; + case Qt::Key_8: + window->movePlayer(Window::Up); + break; + case Qt::Key_6: + window->movePlayer(Window::Right); + break; + case Qt::Key_2: + window->movePlayer(Window::Down); + break; + default: + ; + } + } +//![2] + +private: + Window *window; +}; + +#endif + diff --git a/examples/statemachine/rogue/rogue.pro b/examples/statemachine/rogue/rogue.pro new file mode 100644 index 0000000000..6ab613bea9 --- /dev/null +++ b/examples/statemachine/rogue/rogue.pro @@ -0,0 +1,11 @@ +HEADERS = window.h \ + movementtransition.h +SOURCES = main.cpp \ + window.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/rogue +sources.files = $$SOURCES $$HEADERS *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/rogue +INSTALLS += target sources + diff --git a/examples/statemachine/rogue/window.cpp b/examples/statemachine/rogue/window.cpp new file mode 100644 index 0000000000..39f5aa65d9 --- /dev/null +++ b/examples/statemachine/rogue/window.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "window.h" +#include "movementtransition.h" + +//![0] +Window::Window() +{ + pX = 5; + pY = 5; +//![0] + + QFontDatabase database; + QFont font; + if (database.families().contains("Monospace")) + font = QFont("Monospace", 12); + else { + foreach (QString family, database.families()) { + if (database.isFixedPitch(family)) { + font = QFont(family, 12); + break; + } + } + } + setFont(font); + +//![1] + setupMap(); + buildMachine(); +} +//![1] + +void Window::setStatus(const QString &status) +{ + myStatus = status; + repaint(); +} + +QString Window::status() const +{ + return myStatus; +} + +void Window::paintEvent(QPaintEvent * /* event */) +{ + QFontMetrics metrics(font()); + QPainter painter(this); + int fontHeight = metrics.height(); + int fontWidth = metrics.width('X'); + int yPos = fontHeight; + int xPos; + + painter.fillRect(rect(), Qt::black); + painter.setPen(Qt::white); + + painter.drawText(QPoint(0, yPos), status()); + + for (int y = 0; y < HEIGHT; ++y) { + yPos += fontHeight; + xPos = 0; + + for (int x = 0; x < WIDTH; ++x) { + if (y == pY && x == pX) { + xPos += fontWidth; + continue; + } + + painter.drawText(QPoint(xPos, yPos), map[x][y]); + xPos += fontWidth; + } + } + painter.drawText(QPoint(pX * fontWidth, (pY + 2) * fontHeight), QChar('@')); +} + +QSize Window::sizeHint() const +{ + QFontMetrics metrics(font()); + + return QSize(metrics.width('X') * WIDTH, metrics.height() * (HEIGHT + 1)); +} + +//![2] +void Window::buildMachine() +{ + machine = new QStateMachine; + + QState *inputState = new QState(machine); + inputState->assignProperty(this, "status", "Move the rogue with 2, 4, 6, and 8"); + + MovementTransition *transition = new MovementTransition(this); + inputState->addTransition(transition); +//![2] + +//![3] + QState *quitState = new QState(machine); + quitState->assignProperty(this, "status", "Really quit(y/n)?"); + + QKeyEventTransition *yesTransition = new + QKeyEventTransition(this, QEvent::KeyPress, Qt::Key_Y); + yesTransition->setTargetState(new QFinalState(machine)); + quitState->addTransition(yesTransition); + + QKeyEventTransition *noTransition = + new QKeyEventTransition(this, QEvent::KeyPress, Qt::Key_N); + noTransition->setTargetState(inputState); + quitState->addTransition(noTransition); +//![3] + +//![4] + QKeyEventTransition *quitTransition = + new QKeyEventTransition(this, QEvent::KeyPress, Qt::Key_Q); + quitTransition->setTargetState(quitState); + inputState->addTransition(quitTransition); +//![4] + +//![5] + machine->setInitialState(inputState); + + connect(machine, SIGNAL(finished()), qApp, SLOT(quit())); + + machine->start(); +} +//![5] + +void Window::movePlayer(Direction direction) +{ + switch (direction) { + case Left: + if (map[pX - 1][pY] != '#') + --pX; + break; + case Right: + if (map[pX + 1][pY] != '#') + ++pX; + break; + case Up: + if (map[pX][pY - 1] != '#') + --pY; + break; + case Down: + if (map[pX][pY + 1] != '#') + ++pY; + break; + } + repaint(); +} + +void Window::setupMap() +{ + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + + for (int x = 0; x < WIDTH; ++x) + for (int y = 0; y < HEIGHT; ++y) { + if (x == 0 || x == WIDTH - 1 || y == 0 || y == HEIGHT - 1 || qrand() % 40 == 0) + map[x][y] = '#'; + else + map[x][y] = '.'; + } +} + diff --git a/examples/statemachine/rogue/window.h b/examples/statemachine/rogue/window.h new file mode 100644 index 0000000000..025ec79600 --- /dev/null +++ b/examples/statemachine/rogue/window.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QState; +class QStateMachine; +class QTransition; +QT_END_NAMESPACE + +#define WIDTH 35 +#define HEIGHT 20 + +//![0] +class Window : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString status READ status WRITE setStatus) + +public: + enum Direction { Up, Down, Left, Right }; + + Window(); + + void movePlayer(Direction direction); + void setStatus(const QString &status); + QString status() const; + + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent *event); +//![0] + +//![1] +private: + void buildMachine(); + void setupMap(); + + QChar map[WIDTH][HEIGHT]; + int pX, pY; + + QStateMachine *machine; + QString myStatus; +}; +//![1] + +#endif + diff --git a/examples/statemachine/statemachine.pro b/examples/statemachine/statemachine.pro new file mode 100644 index 0000000000..e5b8b75705 --- /dev/null +++ b/examples/statemachine/statemachine.pro @@ -0,0 +1,18 @@ +TEMPLATE = subdirs +SUBDIRS = \ + factorial \ + pingpong + +!contains(QT_CONFIG, no-gui) { + SUBDIRS += \ + eventtransitions \ + rogue \ + trafficlight \ + twowaybutton +} + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS statemachine.pro README +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine +INSTALLS += target sources diff --git a/examples/statemachine/trafficlight/main.cpp b/examples/statemachine/trafficlight/main.cpp new file mode 100644 index 0000000000..23cd34833a --- /dev/null +++ b/examples/statemachine/trafficlight/main.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +//! [0] +class LightWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(bool on READ isOn WRITE setOn) +public: + LightWidget(const QColor &color, QWidget *parent = 0) + : QWidget(parent), m_color(color), m_on(false) {} + + bool isOn() const + { return m_on; } + void setOn(bool on) + { + if (on == m_on) + return; + m_on = on; + update(); + } + +public slots: + void turnOff() { setOn(false); } + void turnOn() { setOn(true); } + +protected: + virtual void paintEvent(QPaintEvent *) + { + if (!m_on) + return; + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setBrush(m_color); + painter.drawEllipse(0, 0, width(), height()); + } + +private: + QColor m_color; + bool m_on; +}; +//! [0] + +//! [1] +class TrafficLightWidget : public QWidget +{ +public: + TrafficLightWidget(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout *vbox = new QVBoxLayout(this); + m_red = new LightWidget(Qt::red); + vbox->addWidget(m_red); + m_yellow = new LightWidget(Qt::yellow); + vbox->addWidget(m_yellow); + m_green = new LightWidget(Qt::green); + vbox->addWidget(m_green); + QPalette pal = palette(); + pal.setColor(QPalette::Background, Qt::black); + setPalette(pal); + setAutoFillBackground(true); + } + + LightWidget *redLight() const + { return m_red; } + LightWidget *yellowLight() const + { return m_yellow; } + LightWidget *greenLight() const + { return m_green; } + +private: + LightWidget *m_red; + LightWidget *m_yellow; + LightWidget *m_green; +}; +//! [1] + +//! [2] +QState *createLightState(LightWidget *light, int duration, QState *parent = 0) +{ + QState *lightState = new QState(parent); + QTimer *timer = new QTimer(lightState); + timer->setInterval(duration); + timer->setSingleShot(true); + QState *timing = new QState(lightState); + QObject::connect(timing, SIGNAL(entered()), light, SLOT(turnOn())); + QObject::connect(timing, SIGNAL(entered()), timer, SLOT(start())); + QObject::connect(timing, SIGNAL(exited()), light, SLOT(turnOff())); + QFinalState *done = new QFinalState(lightState); + timing->addTransition(timer, SIGNAL(timeout()), done); + lightState->setInitialState(timing); + return lightState; +} +//! [2] + +//! [3] +class TrafficLight : public QWidget +{ +public: + TrafficLight(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout *vbox = new QVBoxLayout(this); + TrafficLightWidget *widget = new TrafficLightWidget(); + vbox->addWidget(widget); + vbox->setMargin(0); + + QStateMachine *machine = new QStateMachine(this); + QState *redGoingYellow = createLightState(widget->redLight(), 3000); + redGoingYellow->setObjectName("redGoingYellow"); + QState *yellowGoingGreen = createLightState(widget->yellowLight(), 1000); + yellowGoingGreen->setObjectName("yellowGoingGreen"); + redGoingYellow->addTransition(redGoingYellow, SIGNAL(finished()), yellowGoingGreen); + QState *greenGoingYellow = createLightState(widget->greenLight(), 3000); + greenGoingYellow->setObjectName("greenGoingYellow"); + yellowGoingGreen->addTransition(yellowGoingGreen, SIGNAL(finished()), greenGoingYellow); + QState *yellowGoingRed = createLightState(widget->yellowLight(), 1000); + yellowGoingRed->setObjectName("yellowGoingRed"); + greenGoingYellow->addTransition(greenGoingYellow, SIGNAL(finished()), yellowGoingRed); + yellowGoingRed->addTransition(yellowGoingRed, SIGNAL(finished()), redGoingYellow); + + machine->addState(redGoingYellow); + machine->addState(yellowGoingGreen); + machine->addState(greenGoingYellow); + machine->addState(yellowGoingRed); + machine->setInitialState(redGoingYellow); + machine->start(); + } +}; +//! [3] + +//! [4] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + TrafficLight widget; + widget.resize(110, 300); + widget.show(); + + return app.exec(); +} +//! [4] + +#include "main.moc" diff --git a/examples/statemachine/trafficlight/trafficlight.pro b/examples/statemachine/trafficlight/trafficlight.pro new file mode 100644 index 0000000000..f6aab8d6e5 --- /dev/null +++ b/examples/statemachine/trafficlight/trafficlight.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/trafficlight +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trafficlight.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/trafficlight +INSTALLS += target sources diff --git a/examples/statemachine/twowaybutton/main.cpp b/examples/statemachine/twowaybutton/main.cpp new file mode 100644 index 0000000000..6b9ce1fe55 --- /dev/null +++ b/examples/statemachine/twowaybutton/main.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +//! [0] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + QPushButton button; + QStateMachine machine; +//! [0] + +//! [1] + QState *off = new QState(); + off->assignProperty(&button, "text", "Off"); + off->setObjectName("off"); + + QState *on = new QState(); + on->setObjectName("on"); + on->assignProperty(&button, "text", "On"); +//! [1] + +//! [2] + off->addTransition(&button, SIGNAL(clicked()), on); + on->addTransition(&button, SIGNAL(clicked()), off); +//! [2] + +//! [3] + machine.addState(off); + machine.addState(on); +//! [3] + +//! [4] + machine.setInitialState(off); + machine.start(); +//! [4] + +//! [5] + button.resize(100, 50); + button.show(); + return app.exec(); +} +//! [5] diff --git a/examples/statemachine/twowaybutton/twowaybutton.pro b/examples/statemachine/twowaybutton/twowaybutton.pro new file mode 100644 index 0000000000..212ba501d7 --- /dev/null +++ b/examples/statemachine/twowaybutton/twowaybutton.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/twowaybutton +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS twowaybutton.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/statemachine/twowaybutton +INSTALLS += target sources |