ВопросQt состояние машины: Как связать один переход с несколькими состояниями
Сейчас я работаю над приложением, используя структуру государственной машины Qt, моя цель состоит в том, чтобы связать один переход с несколькими состояниями источника. Обоснованием для этого является сигнал, вызывающий переход, не зависит от исходного состояния, поэтому вместо нескольких переходов (по одному для каждого исходного состояния) я думал, что было бы лучше иметь его. Я столкнулся с проблемами, связанными с рассмотрением вышеизложенного с помощью Qt. Подробности приведены ниже с помощью тестового состояния. (Ниже упоминается гипотетическая машина состояний, но я могу также привести примеры реальных примеров для такого использования). Просьба предложить несколько эффективных способов для достижения указанной цели.
Фрагмент кода, где проблема лежит
m_s1.addTransition(&m_Trans); // Adding transition to state S1
m_s2.addTransition(&m_Trans); // Adding the same transition to state S2
// As per Qt docs, it seems the ownership of thr transition will be transferred to s2 which is what is causing the problem.
CState.hpp
class CState: public QState
{
public:
/** Constructor */
CState(std::string a_pStateName)
:QState(nullptr),
m_pStateName(a_pStateName)
{
}
/** Overriding on entry */
virtual void onEntry(QEvent *a_pEvent) Q_DECL_OVERRIDE
{
(void) a_pEvent;
printf("State entry %s\n",m_pStateName.c_str());
}
~CState() {}
CState() {}
private:
std::string m_pStateName;
};
CTestMachine.hpp
class CTestStateMachine: public QObject
{
Q_OBJECT
public:
CTestStateMachine();
~CTestStateMachine() {};
private:
QSignalTransition m_Trans;
CState m_s1;
CState m_s2;
CState m_s3;
QStateMachine m_TestMachine;
QTimer m_Timer;
signals:
void SourceIndependentSignal();
public slots:
void TimetoInvokeTrans();
};
CTestMachine.cpp
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#include <QObject>
#include <QCoreApplication>
#include <QStateMachine>
#include <QState>
#include <QSignalTransition>
#include <QTimer>
#include "CState.hpp"
#include "CTestStateMachine.hpp"
void CTestStateMachine::TimetoInvokeTrans()
{
printf("Emitting source independent signal\n");
emit SourceIndependentSignal();
}
CTestStateMachine::CTestStateMachine():
m_Trans(this, SIGNAL(SourceIndependentSignal())),
m_s1("s1"),
m_s2("s2"),
m_s3("s3")
{
/* Setup state machine */
m_Trans.setTargetState(&m_s3);
m_s1.addTransition(&m_Trans);
m_s2.addTransition(&m_Trans);
m_TestMachine.addState(&m_s1);
m_TestMachine.addState(&m_s2);
m_TestMachine.addState(&m_s3);
m_TestMachine.setInitialState(&m_s1);
m_TestMachine.start();
printf("Started state machine\n");
/* Trigger timer to make transitions */
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(TimetoInvokeTrans()));
m_Timer.start(1000);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
CTestStateMachine TestMachine;
return a.exec();
}
Почему бы не использовать другие [перегрузки] (http://doc.qt.io/qt-5/qstate.html#addTransition-1) от 'addTransition'? – Rostislav
Поскольку я хотел бы переопределить 'OnTransition' путем подкласса' QSignalTransition', –
Ну, учитывая, что 'QAbstractTransition', кажется, всегда имеет только одно исходное состояние, я бы сказал, что вам нужно будет найти другой подход, например, общего состояния для нескольких экземпляров вашего подкласса 'QSignalTransition'. – Rostislav