87
Towards Animations [email protected]

Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 2: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

créditsEric Lecolinet

Page 3: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

gconftool-2 --type Boolean --set /desktop/gnome/interface/menus_have_icons True

Mes icones ne s’affichaient pas dans mon menu…

C’était la faute d'Ubuntu

Page 4: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les
Page 5: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Signaux et Slots• Comment connecter un signal à un slot ?

• QObject::connect() • Quel code pour déclarer / implémenter un slot ?

• public slots: (.h) • Est ce qu’un slot peut retourner une valeur ?

• Oui • Quel code pour déclarer / implémenter un signal ?

• signals (.h) • emit (.cpp)

• Où et Quand j’utilise Q_OBJECT ? • Premiere élèment dans la class (.h) • signals et/ou slots

Page 6: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Compilation & QMake

• Quand est ce que je fais make ? • à chaque changement dans le code

• Quand est ce que je fais qmake ? • à chaque changement concernant les signaux et les

slots • Quand est ce que je fais qmake -project

• quand je rajoute / supprime un fichier

Page 7: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QWidgets• Quelle est la différence entre l’arbre d’héritage et l’arbre

d’instanciation? • héritage de classe (A hérite de B) • héritage d’instances (A contient B)

• Quelle classe utiliser pour créer une fenêtre • QMainWindow

• Quels sont les différents layouts? • QVBoxLayout; QHBoxLayout; QGridLayout; QFormLayout

• Comment afficher une trace? • #include <QDebug> • qdebug() << “ma trace”;

Page 8: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Dessin• De quelle classe doit-on hériter?

• QWidget • Quelle méthode doit-on réimplémenter?

• void paintEvent(QPaintEvent *e); • Comment demander le réaffichage d’un widget

• update() • repaint()

• Quelle est la différence entre update() et repaint()? • update() indique qu’une zone est à réafficher

(mais l’affichage n’est pas instantané) • repaint() réaffiche immédiatement

(mais peut introduire de la latence) • Comment dessiner dans paintEvent(QPaintEvent*)

• instancier un QPainter: QPainter(this)

Page 9: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

9

Page 10: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Animations

State Machine Properties

Page 12: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Objectifs

• Introduction aux machines à états• création de votre machine à états avec Qt• Aller un peu plus loin…

Page 13: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Introduction

2

Page 14: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

State Machine Framework

• Qu’est ce que c’est ?• API C++

• Créer, interprétater, exécuter

• Hierarchical Finite State Machine (HFSMs)

• W3C SCXML

• Pourquoi ?• Comportement

• QEvent

• void mousePressEvent(QMouseEvent*);

Page 15: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Difficile • à comprendre

• à maintenir

• à étendre

Solution• Machine à états

Constat

Page 16: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Prenons du recul

Page 17: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états finis

Example : rubber banding (repris de Scott Hudson - CMU)

Quel est le problème ?

Accept the press for endpoint p1;

P2 = P1;

Draw line P1-P2;

Repeat

Erase line P1-P2;

P2 = current_position();

Draw line P1-P2;

Until release event;

Act on line input;

Page 18: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états finis

Rubber banding

Problème - pas compatible avec la gestion événementielle

Accept the press for endpoint p1;

P2 = P1;

Draw line P1-P2;

Repeat

Erase line P1-P2;

P2 = current_position();

Draw line P1-P2;

Until release event;

Act on line input;

Page 19: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Rappel : gestion des événements

void paintEvent(QPaintEvent* e) { ......}

Cycle événement / réaffichage - on ne doit pas bloquer ce cycle ni ignorer les (autres) événements

événements

boucle de gestiondes événements

void mySlot() ...... update(); }

Page 20: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Définition d’une machine à états

(indépendent de Qt)

3

Page 21: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états (1/2): Etat

Une solution appropriée pour « maintenir l’état » !- simple et efficace pour modéliser les comportements- évite les «spaghettis de callbacks»- évite la multiplication des variables d’état- évite les erreurs ! - passage facile d’une représentation visuelle au code source- divers outils, UML, QState

Etat Etat de départ Etat final

NB: en IHM généralement pas d’état final : on revient à l’état initial

Page 22: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états (2/2) : Transitions

Représentées par des arcs avec un label : Evénement / Action Si on est dans l’état A et cet événement se produit

• cette action est effectuée• puis on passe dans l’état B

Remarque : les actions sont parfois sur les états • i.e. quand on entre / sort de l’état • au lieu d’être sur les transitions

B A

Mouse_Dn / Draw_Line()

Page 23: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états

Retour à notre «ligne élastique»

Accept the press for endpoint p1;

P2 = P1;

Draw line P1-P2;

Repeat

Erase line P1-P2;

P2 = current_position();

Draw line P1-P2;

Until release event;

Act on line input;

A

B

C

Page 24: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états

Accept the press for endpoint p1;

P2 = P1;

Draw line P1-P2;

Repeat

Erase line P1-P2;

P2 = current_position();

Draw line P1-P2;

Until release event;

Act on line input;

A

B

C

Press / A

Move / B

Release / C

Page 25: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Brainstorming <30s>

Quelle est la machine à état d’un bouton?

Page 26: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états

Autre exemple : bouton

Press-inside / A

Leave / B Enter / C

Release / E

Release / D

A: highlight button B: unhighlight button C: highlight button D: do button action E: do nothing

Page 27: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les
Page 28: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Machines à états

- Evénements : de plus ou moins haut niveau• peuvent aussi être des timeouts (cf. QTimer)

- Gardes • condition supplémentaire • notation : prédicat : événement / action • exemple: button.enabled: press-inside / A

Remarques

Page 29: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

State fsm_transition(state, event) {

switch(state) {

case 1:

switch(event.kind) {

case MouseMove:

action_B();

state = 1;

case MouseRelease:

action_C()

state = 2;

}

break;

case 0:

switch(eventt.kind) {

case ...

}

}

return state;

}

Page 30: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

SwingStates

Implementation Java - Caroline Appert, LRI

- http://swingstates.sourceforge.net/

- classe Canvas qui facilite le dessin interactif

- exemples d’interactions avancées

Page 31: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Créer sa machine à états avec Qt

4

Page 32: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QState QAbstractTransition

QStateMachine

Page 33: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QStateMachine machine;

QState *s1 = new QState(); QState *s2 = new QState(); QState *s3 = new QState();

s1->addTransition(button, SIGNAL(clicked()), s2); s2->addTransition(button, SIGNAL(clicked()), s3); s3->addTransition(button, SIGNAL(clicked()), s1);

machine.addState(s1); machine.addState(s2); machine.addState(s3); machine.setInitialState(s1);

machine.start();

Page 34: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

s1->assignProperty(label, "text", "In state s1"); s2->assignProperty(button, "geometry", QRectF(0,0,50,50));

Property

connect(s3, SIGNAL(entered()), button, SLOT(showMaximized())); connect(s3, SIGNAL(exited()), button, SLOT(showMinimized()));

Signaux sur entrée /sortie d’états

QAbstractTransition * trans = s1->addTransition(obj, SiGNAL(mySignal(), s2);

connect(trans, SIGNAL(triggered()), myObject, SLOT(mySlot()));

Appel de méthode sur une transition

Page 35: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Questions/réponses• Quelles sont les trois composants (classes) d’une

machine à états • QStateMachine; QState; QAbstractTransition

• Comment traduire ca?

• s1->addTransition(button, SIGNAL(clicked()), s2); • Est ce que les actions sont exécutés sur les états ou

sur les transitions? • Transitions • Mais aussi à l’entrée et à la sortie des états

Page 36: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Un peu plus loin avec les machines à états

5 - machines à états hiérarchiques- types de transitions- transitions maisons

Page 37: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les
Page 38: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Hiérarchies// s11, s12, s13 sont groupés dans s1 QState *s1 = new QState( ); QState *s11 = new QState(s1); QState *s12 = new QState(s1); QState *s13 = new QState(s1); s11->addTransition(button, SIGNAL(clicked( )), s12); …etc… s1->setInitialState(s11); // s2 est un étal final QFinalState *s2 = new QFinalState( );

// les enfants de s1 héritent de la transition s1 -> s2 s1->addTransition(quitButton, SIGNAL(clicked( )), s2);

mac->addState(s1); mac->addState(s2); mac->setInitialState(s1); mac->start( );

Page 39: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

HiérarchiesAvantages

- permettent de simplifier les schémas- les états enfants héritent des transitions des états parents

Exemple 2 - 4 radio boutons exclusifs - noter les transitions de l'état parent vers les enfants

solution hiérarchiquesolution « plate »

Page 40: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Types de transitionsPour les signaux

- QSignalTransition : c'est ce qu'on a utilisé jusqu'à présent via :s1->addTransition(button, SIGNAL(clicked( )), s2);

Pour les événements - QEventTransition- QKeyEventTransition- QMouseEventTransition

On peut aussi créer ses propres transitions - en dérivant QAbstractTransition

Page 41: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Header « maison » Transitions.hbutton.clicked / this.doIt()

QAbstractTransition * trans = A->addTransition(button, SiGNAL(clicked(), B);

connect(trans, SIGNAL(triggered()), this, SLOT(doIt())); C’est un peu verbeux…

addTrans(A,B, button, SiGNAL(clicked(), this, SLOT(doIt()));

Page 42: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Header « maison » Transitions.h Ce header définit

- des fonctions simplifiées pour les cas courants- cas des signaux :

QSignalTransition* addTrans( QState* from, QState* to, QObject* sender, const char* signal )

QSignalTransition* addTrans( QState* from, QState* to, QObject* sender, const char* signal, QObject* receiver, const char* slot )

addTrans(A,B, button, SiGNAL(clicked(), this, SLOT(doIt()));

Page 43: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Transitions sur les événementsEvénements quelconques QEventTransition* addEventTrans( QState* from, QState* to, QObject* source, QEvent::Type eventType )

QEventTransition* addEventTrans( QState* from, QState* to, QObject* source, QEvent::Type eventType, QObject* receiver, const char* slot )

Exemple

addEventTrans(out, in, widget, QEvent::Enter); addEventTrans(in, out, widget, QEvent::Leave );

Note - compatible avec événements ad hoc

(définis par le programmeur)

widget.Enter

widget.Leave

in out

Page 44: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Transitions sur les événements

// transition de s1 vers s2 quand le bouton gauche de la souris est pressé sur «canvas» addMouseTrans( s1, s2, canvas, QEvent::MouseButtonPress, Qt::LeftButton, this, SLOT(newLine( )) );

addMouseTrans( s2, s2, canvas, QEvent::MouseMove, Qt::NoButton, // ATT: NoButton pour MouseMove ! this, SLOT(adjustLine( )) );

addMouseTrans( s2, s1, canvas, QEvent::MouseButtonRelease, Qt::LeftButton );

Evénements souris - même principe- on peut spécifier les boutons

Page 45: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Transitions sur les événements

// il faut appuyer LeftButton et RightButton addMouseTrans( s1, s2, canvas, QEvent::MouseButtonPress, Qt::LeftButton | Qt::RightButton );

// double clic addMouseTrans( s1, s2, canvas, QEvent::MouseButtonDblClick, Qt::LeftButton );

// il faut appuyer SHIFT et LeftButton addMouseTrans( s1, s2, canvas, QEvent::MouseButtonPress, Qt::LeftButton ) ->setModifierMask( Qt::ShiftModifier );

Evénements souris (2) - variantes- modifieurs clavier

Page 46: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Transitions sur les événements

Problème addMouseTrans( s1, s2, canvas, QEvent::MouseButtonPress, Qt::LeftButton, this, SLOT(newLine( )) );

addMouseTrans( s2, s2, canvas, QEvent::MouseMove, Qt::NoButton, this, SLOT(adjustLine( )) );

addMouseTrans( s2, s1, canvas, QEvent::MouseButtonRelease, Qt::LeftButton );

newLine() et adjustLine() n'ont pas de paramètre QEvent !

=> comment peuvent-elles accéder à la position du curseur ?

Page 47: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Position du curseurSolution 1 QPoint cursorPos(QWidget* w) { return w->mapFromGlobal(QCursor::pos( )); }

- attention : petit décalage possible sur systèmes asynchrones (e.g. X11 en réseau)

Page 48: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Position du curseurSolution 2

- variante de addMouseTrans( ) - pos contiendra la position du curseur mise à jour à chaque transition

QPoint pos;

addMouseTrans( s2, s2, canvas, QEvent::MouseMove, Qt::NoButton, pos);

Page 50: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Animations

State Machine Properties

Page 51: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QProperty

• The Meta-object system (QObject) • Introspection des objects

• utile pour QtDesigner

51

QWidget* w = new QLabel();Question : Quels sont les propriétés de w?

Réponse : w->dynamicProperties();

Page 52: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QProperty class MyClass : public QObject { Q_OBJECT Q_PROPERTY(Type m_var READ var WRITE setVar)

public:void setVar(const Type& v){ m_var = v;}const Type& var(){ return m_var; }

protected:Type m_var;

};

//Type parmis : // int, float, QRect, QPos, QSize, etc.

Page 53: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les
Page 54: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QPushButton *button = new QPushButton;QObject *object = button;

button->setFlat(true);object->setProperty("flat", true); lent

rapide

Page 56: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Animations

• Définition: • Une série d’images. Chaque image est montrée

pendant un temps fixe. • Approches

• QTimer • QTimeLine • QAnimation framework

56

Page 57: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QTimerQTimer* timer = new QTimer(); connect(timer, SIGNAL( timeout() ),

this, SLOT( doSomething() ) ); timer->setSingleShot(false); //est répété indéfiniment timer->start(1000); … timer->stop();

57

Simple, mais peu puissant

Page 58: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QTimeLine

58

QProgressBar *progress = new QProgressBar(); progress->setRange(0,100);

QTimeLine* timeLine = new QTimeLine(1000); //duration = 1s (1000ms) timeLine->setFrameRange(0,100); //par défaut [0;40] connect(timeLine, SIGNAL( frameChange(int) ),

progress, SLOT( setValue(int) ) ); timeLine->setLoopCount(10); //répété 10 fois

timeLine->setCurveShape(Qt::EaseInOutCurve); //par défaut.

un peu plus puissant

Page 59: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

59

//Linear, InQuad, OutQuad, InOutQuad, ..., Custom (45 différentes)

QTimeLine: CurveShape

Page 60: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Animation Framework

• permet d’animer des Objects (et donc des QWidgets)

• S’appuie sur les QProperty • peut aussi s’appuyer sur les machines à

états. • Plus de fonctionnalités

• ex: groupes

60

Plus simple, plus puissant, meilleure intégration

Page 61: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QPropertyAnimation animation(myWidget, "geometry"); animation.setDuration(10000); animation.setStartValue(QRect(0, 0, 100, 30)); animation.setEndValue(QRect(250, 250, 100, 30));

animation.setEasingCurve(QEasingCurve::InOutSine); //Linear, InQuad, OutQuad, InOutQuad, ..., Custom (45 différentes)

animation.start();//animation.stop();

QProperty

Animation linéaire par défaut

Exemple

Page 62: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QPropertyAnimation animation(myWidget, "geometry"); animation.setDuration(10000); animation.setStartValue(QRect(0, 0, 100, 30)); animation.setEndValue(QRect(250, 250, 100, 30));

animation.setKeyValueAt(0,QRect(0, 0, 100, 30)); animation.setKeyValueAt(0.8,QRect(100, 150, 100, 30)); animation.setKeyValueAt(1,QRect(250, 250, 100, 30));

animation.setEasingCurve(QEasingCurve::InOutSine); //Linear, InQuad, OutQuad, InOutQuad, ..., Custom (45 différentes)

animation.start();//animation.stop();

QProperty

Exemple

Page 63: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

La base de toute animation

(start, stop, pause)

Contrôler les propriétés des widgets (color; size; etc.)

Gérer des groupes d'animations

Page 64: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Animation Framework

• Peut être utilisé tout seul… …mais aussi avec les machines à états

64

Page 65: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Animation & State Machine

QState *s1 = new QState(); s1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));

QState *2 = new QState(); s2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));

QSignalTransition *trans1 = s1->addTransition(button, SIGNAL(clicked()), s2);

trans1->addAnimation(new QPropertyAnimation(button, "geometry"));

QSignalTransition *trans2 = state2->addTransition(button, SIGNAL(clicked()), s1);

trans2->addAnimation(new QPropertyAnimation(button, "geometry"));

Page 66: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Questions/réponses• Quelles sont les 3 approches pour les animations

• QTimer; QTimeLine; QAnimationFramework • Sur quels concepts s’appuient le

Animation Framework • QProperty and QStateMachine

• Comment définit on une QProperty • Q_OBJECT • QPROPERTY(Type m_var READ var WRITE setVar)

Page 67: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QStateMachine machine;

QState *s1 = new QState(); QState *s2 = new QState(); QState *s3 = new QState();

s1->addTransition(button, SIGNAL(clicked()), s2); s2->addTransition(button, SIGNAL(clicked()), s3); s3->addTransition(button, SIGNAL(clicked()), s1);

machine.addState(s1); machine.addState(s2); machine.addState(s3); machine.setInitialState(s1);

machine.start();

Page 68: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les
Page 70: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Génère une description xml de votre interface (.ui)

Page 71: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

QProperties

Page 72: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Génère une description xml de votre interface (.ui)

Page 73: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Comment intégrer les ".ui" dans votre programme?

Page 74: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

3 approches• Approche 1

– On « charge » notre widget dans notre programme

• Approche 2 – Héritage simple

• Approche 3 – Héritage multiple

Page 75: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Approche 1

• Fichiers – main.cpp – calculatorform.ui

– calculator.pro

TEMPLATE = app FORMS = calculatorform.ui SOURCES = main.cpp

Page 76: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Approche 1

• main.cpp #include "ui_calculatorform.h"

int main (int argc, char *argv[]) { Qapplication app(argc, argv); Qwidget *widget = new Qwidget(); Ui::CalculatorForm ui; ui.setupUi(widget);

widget->show(); return app.exec(); }

uic: transforme un fichier xml (myform.ui) en un fichier d’entête (ui_myform_.h

Page 77: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Approche 1

• Avantages : – rapide et facile à intégrer

• Inconvénients : – peu de flexibilité – Comment afficher le résultat dans le Qlabel ?

Page 78: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Approche 2: héritage simple

• Fichiers – main.cpp – calculatorform.ui – calculatorform.h – calculator.pro

TEMPLATE = app FORMS = calculatorform.ui SOURCES = main.cpp HEADERS = calculatorform.h

Page 79: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• main.cpp#include "calculatorform.h" (pas de ui)

int main (int argc, char *argv[]) { Qapplication app(argc, argv); calculator widget;

widget.show(); return app.exec(); }

Approche 2: héritage simple

Page 80: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• calculatorForm.h#include "ui_calculatorform.h"

Class Calculator : public QWidget { Q_OBJECT public: CalculatorForm(Qwidget *parent =0);

private slots: void on_inputSpinBox1_valueChanged(int value); void on_inputSpinBox2_valueChanged(int value); private Ui::CalculatorForm ui; }

Auto-connect

Approche 2: héritage simple

Page 81: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• calculatorForm.cpp

CalculatorForm::CalculatorForm(Qwidget *parent):Qwidget( parent) { ui.setupUi(this); }

void CalculatorForm::on_inputSpinBox1_valueChanged(int value) { QString res =QString::number(value + ui.inputSpinBox2->value()); ui.outputWidget->setText(res); }

Approche 2: héritage simple

Page 82: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• Avantages : – Plus flexible

• Inconvénients : – Un peu plus de code …

Approche 2: héritage simple

Page 83: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

Approche 3 : héritage multiple

• Fichiers – main.cpp – calculatorform.ui – calculatorform.h – calculator.pro

TEMPLATE = app FORMS = calculatorform.ui SOURCES = main.cpp HEADERS = calculatorform.h

Pareil que l’approche 2

Page 84: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• main.cpp#include "calculatorform.h » (pas de ui)

int main (int argc, char *argv[]) { Qapplication app(argc, argv); CalculatorForm widget;

widget.show(); return app.exec(); }

Approche 3 : héritage multiple

Page 85: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• calculatorForm.h

#include "ui_calculatorform.h"

Class CalculatorFrom : public QWidget, private Ui::CalculatorForm { Q_OBJECT public: CalculatorForm(Qwidget *parent =0);

}

Approche 3 : héritage multiple

Page 86: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• calculatorForm.cpp

CalculatorForm::CalculatorForm(Qwidget *parent):Qwidget( parent) { setupUi(this); (différent de ui.setupUi(this))

inputSpinBox1->…. (acces direct aux éléments) }

Approche 3 : héritage multiple

Page 87: Towards Animations · Machines à états (1/2): Etat Une solution appropriée pour « maintenir l’état » ! - simple et efficace pour modéliser les comportements - évite les

• Avantages : – Encore plus flexible

• Acces direct aux variables – Fichier généré automatiquement dans Qt

Creator • Inconvénients :

– Un peu plus de code …

Approche 3 : héritage multiple