main.cpp Example File | Qt Widgets 5.12.10

- Qt 5.12
- Qt Widgets
- Move Blocks Example
- main.cpp Example File
- Qt 5.12.10 Reference Documentation

# main.cpp Example File

animation/moveblocks/main.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2016 The Qt Company Ltd.
     ** Contact: https://www.qt.io/licensing/
     **
     ** This file is part of the QtCore module of the Qt Toolkit.
     **
     ** $QT_BEGIN_LICENSE:BSD$
     ** Commercial License Usage
     ** Licensees holding valid commercial Qt licenses may use this file in
     ** accordance with the commercial license agreement provided with the
     ** Software or, alternatively, in accordance with the terms contained in
     ** a written agreement between you and The Qt Company. For licensing terms
     ** and conditions see https://www.qt.io/terms-conditions. For further
     ** information use the contact form at https://www.qt.io/contact-us.
     **
     ** BSD License Usage
     ** Alternatively, 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 The Qt Company Ltd 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 <QtWidgets>

     class StateSwitchEvent: public QEvent
     {
     public:
         StateSwitchEvent()
             : QEvent(Type(StateSwitchType))
         {
         }

         explicit StateSwitchEvent(int rand)
             : QEvent(Type(StateSwitchType)),
               m_rand(rand)
         {
         }

         enum { StateSwitchType = QEvent::User + 256 };

         int rand() const { return m_rand; }

     private:
         int m_rand;
     };

     class QGraphicsRectWidget : public QGraphicsWidget
     {
     public:
         void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
                    QWidget *) override
         {
             painter->fillRect(rect(), Qt::blue);
         }
     };

     class StateSwitchTransition: public QAbstractTransition
     {
     public:
         StateSwitchTransition(int rand)
             : QAbstractTransition(),
               m_rand(rand)
         {
         }

     protected:
         bool eventTest(QEvent *event) override
         {
             return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType))
                 && (static_cast<StateSwitchEvent *>(event)->rand() == m_rand);
         }

         void onTransition(QEvent *) override {}

     private:
         int m_rand;
     };

     class StateSwitcher : public QState
     {
         Q_OBJECT
     public:
         StateSwitcher(QStateMachine *machine)
             : QState(machine), m_stateCount(0), m_lastIndex(0)
         { }

         void onEntry(QEvent *) override
         {
             int n;
             while ((n = QRandomGenerator::global()->bounded(m_stateCount) + 1) == m_lastIndex)
             { }
             m_lastIndex = n;
             machine()->postEvent(new StateSwitchEvent(n));
         }
         void onExit(QEvent *) override {}

         void addState(QState *state, QAbstractAnimation *animation) {
             StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount);
             trans->setTargetState(state);
             addTransition(trans);
             trans->addAnimation(animation);
         }

     private:
         int m_stateCount;
         int m_lastIndex;
     };

     QState *createGeometryState(QObject *w1, const QRect &rect1,
                                 QObject *w2, const QRect &rect2,
                                 QObject *w3, const QRect &rect3,
                                 QObject *w4, const QRect &rect4,
                                 QState *parent)
     {
         QState *result = new QState(parent);
         result->assignProperty(w1, "geometry", rect1);
         result->assignProperty(w2, "geometry", rect2);
         result->assignProperty(w3, "geometry", rect3);
         result->assignProperty(w4, "geometry", rect4);

         return result;
     }

     class GraphicsView : public QGraphicsView
     {
         Q_OBJECT
     public:
         GraphicsView(QGraphicsScene *scene, QWidget *parent = NULL) : QGraphicsView(scene, parent)
         {
         }

     protected:
         void resizeEvent(QResizeEvent *event) override
         {
             fitInView(scene()->sceneRect());
             QGraphicsView::resizeEvent(event);
         }
     };

     int main(int argc, char **argv)
     {
         QApplication app(argc, argv);

         QGraphicsRectWidget *button1 = new QGraphicsRectWidget;
         QGraphicsRectWidget *button2 = new QGraphicsRectWidget;
         QGraphicsRectWidget *button3 = new QGraphicsRectWidget;
         QGraphicsRectWidget *button4 = new QGraphicsRectWidget;
         button2->setZValue(1);
         button3->setZValue(2);
         button4->setZValue(3);
         QGraphicsScene scene(0, 0, 300, 300);
         scene.setBackgroundBrush(Qt::black);
         scene.addItem(button1);
         scene.addItem(button2);
         scene.addItem(button3);
         scene.addItem(button4);
         GraphicsView window(&scene);
         window.setFrameStyle(0);
         window.setAlignment(Qt::AlignLeft | Qt::AlignTop);
         window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
         window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
         QStateMachine machine;

         QState *group = new QState();
         group->setObjectName("group");
         QTimer timer;
         timer.setInterval(1250);
         timer.setSingleShot(true);
         QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start()));

         QState *state1;
         QState *state2;
         QState *state3;
         QState *state4;
         QState *state5;
         QState *state6;
         QState *state7;

         state1 = createGeometryState(button1, QRect(100, 0, 50, 50),
                                      button2, QRect(150, 0, 50, 50),
                                      button3, QRect(200, 0, 50, 50),
                                      button4, QRect(250, 0, 50, 50),
                                      group);
         state2 = createGeometryState(button1, QRect(250, 100, 50, 50),
                                      button2, QRect(250, 150, 50, 50),
                                      button3, QRect(250, 200, 50, 50),
                                      button4, QRect(250, 250, 50, 50),
                                      group);
         state3 = createGeometryState(button1, QRect(150, 250, 50, 50),
                                      button2, QRect(100, 250, 50, 50),
                                      button3, QRect(50, 250, 50, 50),
                                      button4, QRect(0, 250, 50, 50),
                                      group);
         state4 = createGeometryState(button1, QRect(0, 150, 50, 50),
                                      button2, QRect(0, 100, 50, 50),
                                      button3, QRect(0, 50, 50, 50),
                                      button4, QRect(0, 0, 50, 50),
                                      group);
         state5 = createGeometryState(button1, QRect(100, 100, 50, 50),
                                      button2, QRect(150, 100, 50, 50),
                                      button3, QRect(100, 150, 50, 50),
                                      button4, QRect(150, 150, 50, 50),
                                      group);
         state6 = createGeometryState(button1, QRect(50, 50, 50, 50),
                                      button2, QRect(200, 50, 50, 50),
                                      button3, QRect(50, 200, 50, 50),
                                      button4, QRect(200, 200, 50, 50),
                                      group);
         state7 = createGeometryState(button1, QRect(0, 0, 50, 50),
                                      button2, QRect(250, 0, 50, 50),
                                      button3, QRect(0, 250, 50, 50),
                                      button4, QRect(250, 250, 50, 50),
                                      group);
         group->setInitialState(state1);

         QParallelAnimationGroup animationGroup;
         QSequentialAnimationGroup *subGroup;

         QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry");
         anim->setDuration(1000);
         anim->setEasingCurve(QEasingCurve::OutElastic);
         animationGroup.addAnimation(anim);

         subGroup = new QSequentialAnimationGroup(&animationGroup);
         subGroup->addPause(100);
         anim = new QPropertyAnimation(button3, "geometry");
         anim->setDuration(1000);
         anim->setEasingCurve(QEasingCurve::OutElastic);
         subGroup->addAnimation(anim);

         subGroup = new QSequentialAnimationGroup(&animationGroup);
         subGroup->addPause(150);
         anim = new QPropertyAnimation(button2, "geometry");
         anim->setDuration(1000);
         anim->setEasingCurve(QEasingCurve::OutElastic);
         subGroup->addAnimation(anim);

         subGroup = new QSequentialAnimationGroup(&animationGroup);
         subGroup->addPause(200);
         anim = new QPropertyAnimation(button1, "geometry");
         anim->setDuration(1000);
         anim->setEasingCurve(QEasingCurve::OutElastic);
         subGroup->addAnimation(anim);

         StateSwitcher *stateSwitcher = new StateSwitcher(&machine);
         stateSwitcher->setObjectName("stateSwitcher");
         group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher);
         stateSwitcher->addState(state1, &animationGroup);
         stateSwitcher->addState(state2, &animationGroup);
         stateSwitcher->addState(state3, &animationGroup);
         stateSwitcher->addState(state4, &animationGroup);
         stateSwitcher->addState(state5, &animationGroup);
         stateSwitcher->addState(state6, &animationGroup);
         stateSwitcher->addState(state7, &animationGroup);

         machine.addState(group);
         machine.setInitialState(group);
         machine.start();

         window.resize(300, 300);
         window.show();

         return app.exec();
     }

     #include "main.moc"