c++ - Emitting signals from class, if transition in QStateMachine was successful -


my problem following: need create class, contains qstatemachine instance. class should have slots through "ask" state machine make transition state. , if transition successful, class should emit signal it. how implement this? class should have ability emit signals according slot invoke. here small example of class:

class myclass : public qobject {     q_object public:     explicit myclass(qobject *parent = 0)     {         mstatemachine = new qstatemachine(this);         qstate *s1 = new qstate(mstatemachine);         qstate *s2 = new qstate(mstatemachine);         qstate *s3 = new qstate(mstatemachine);          s1->addtransition(); // transition s2         s2->addtransition(); // transition s3         s3->addtransition(); // transition s1          mstatemachine->setinitialstate(s1);         mstatemachine->start();     }  signals:     tos1();     tos2();     tos3();  public slots:     slottos1()     {         /* post event state machine         transition state s1,         if transition successful,         emit tos1() signal. */     };     slottos2(){ /* similar slottos1 */};     slottos3(){ /* similar slottos1 */}; private:     qstatemachine *mstatemachine; } 

i grateful help!

upd:
slots representing defferent kinds of transitions, outer class (that using myclass) 'ask' transition. so, slot send event or signal state machine, looks on event or signal , (if in right state) makes transition. , want notify outer class signal, asked before slot (transition) made successfuly.

  1. to transition on slot call, need somehow bind slot qabstracttransition. there 2 ways of doing it:

    • use qeventtransition , send relevant event trigger it.

    • use qsignaltransition , use internal signal trigger it.

  2. to emit signals on state transitions, can connect qabstracttransition::triggered or qstate::entered or qstate::exited signals other signals. remember, in qt connection target can either slot or signal.

thus, using signal transitions:

class myclass : public qobject {   q_object   qstatemachine machine;   qstate s1, s2;   q_signal void s_go_s1_s2();   q_signal void s_go_s2_s1(); public:   q_signal void transitioned_s1_s2();   q_signal void transitioned_s2_s1();   q_slot void go_s2_s1() { emit s_go_s2_s1(); }   q_slot void go_s1_s2() { emit s_go_s1_s2(); }   explicit myclass(qobject *parent = 0) : qobject(parent),     s1(&machine), s2(&machine) {     auto s1_s2 = s1.addtransition(this, signal(s_go_s1_s2()), &s2);     auto s2_s1 = s2.addtransition(this, signal(s_go_s2_s1()), &s1);     machine.setinitialstate(&s1);     machine.start();     connect(s1_s2, &qabstracttransition::triggered, this, &myclass:: transitioned_s1_s2);     connect(s2_s1, &qabstracttransition::triggered, this, &myclass:: transitioned_s2_s1);   } } 

using event transitions bit harder, since events you're using must cloneable state machine. core module's state machine knows how clone none , timer events - see cloneevent implementation.

the widgets module adds support various gui/widgets events - see cloneevent implementation there. could, in pinch, use such gui events own purposes - after all, sent plain qobject doesn't interpret them in special way.

you can provide own cloneevent implementation links others.

#include <private/qstatemachine_p.h>  class myclass : public qobject {   q_object   qstatemachine machine;   qstate s1, s2;   qevent e_s1_s2, e_s2_s1;   qeventtransition s1_s2, s2_s1; public:   q_signal void transitioned_s1_s2();   q_signal void transitioned_s2_s1();   q_slot void go_s2_s1() { qcoreapplication::sendevent(this, &e_s2_s1); }   q_slot void go_s1_s2() { qcoreapplication::sendevent(this, &e_s1_s2); }   explicit myclass(qobject *parent = 0) : qobject(parent),     s1(&machine), s2(&machine),     e_s1_s2((qevent::type)(qevent::user + 1)),     e_s2_s1((qevent::type)(qevent::user + 2)),     s1_s2(this, e_s1_s2.type()),     s2_s1(this, e_s2_s1.type()) {     s1_s2.settargetstate(&s2);     s2_s1.settargetstate(&s1);     s1.addtransition(&s1_s2);     s2.addtransition(&s2_s1);     machine.setinitialstate(&s1);     machine.start();     connect(&s1_s2, &qabstracttransition::triggered, this, &myclass::transitioned_s1_s2);     connect(&s2_s1, &qabstracttransition::triggered, this, &myclass::transitioned_s2_s1);   } }  static const qstatemachineprivate::handler * last_handler = 0;  static qevent * cloneevent(qevent * e) {   if (e->type() >= qevent::user && e->type() < qevent::user+100) {     return new qevent(e->type());   return last_handler->cloneevent(e); }  const qstatemachineprivate::handler our_handler = {     cloneevent };  void registerhandler() {   last_handler = qstatemachineprivate::handler;   qstatemachineprivate::handler = &our_handler; } q_constructor_function(registerhandler())  void unregisterhandler() {   qstatemachineprivate::handler = last_handler;  } q_destructor_function(unregisterhandler()) 

Comments

Popular posts from this blog

searchKeyword not working in AngularJS filter -

sequelize.js - Sequelize: sort by enum cases -

user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -