Я пытаюсь реализовать простой конечный автомат в консольном приложении. Сигналы, которые должны инициировать переходы состояния, испускаются, однако конечный автомат не реагирует на эти сигналы.QStateMachine не работает правильно при использовании QCoreApplication
Этот конечный автомат отлично работает при работе в QApplication (то есть графическом приложении), однако я хочу разработать консольное приложение. Я подозреваю, что проблема в том, как я реализовал цикл событий, поскольку QStateMachine не испускает сигнал start().
Каков правильный способ выполнения приложения для правильной работы конечного автомата?
main.cpp:
#include <QCoreApplication>
#include "test.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Test test;
QMetaObject::invokeMethod(&test, "Run", Qt::QueuedConnection);
return a.exec();
}
test.h:
#ifndef TEST_H
#define TEST_H
#include <QObject>
#include <QStateMachine>
class Test : public QObject
{
Q_OBJECT
public:
explicit Test(QObject *parent = 0) : QObject(parent) {}
public slots:
void Run();
signals:
void stateChanged();
void debugSignal();
private:
void buildStateMachine();
QStateMachine machine;
private slots:
void runS1();
void runS2();
void runS3();
void debugSlot();
};
#endif // TEST_H
test.cpp:
#include "test.h"
#include <QDebug>
void Test::Run()
{
buildStateMachine();
QTextStream qin(stdin);
while (true)
{
QString line = qin.readLine();
qDebug() << "line: " << line;
if (line == "A")
{
qDebug() << "emit stateChanged signal";
emit stateChanged();
}
else if (line == "B")
{
qDebug() << "emit debugSignal";
emit debugSignal();
}
}
}
void Test::buildStateMachine()
{
connect(&machine, SIGNAL(started()), this, SLOT(debugSlot())); // doesn't seem to get triggered... (why is machine not starting?)
connect(this, SIGNAL(debugSignal()), this, SLOT(debugSlot())); // works as expected
QState *s1 = new QState(&machine);
QState *s2 = new QState(&machine);
QState *s3 = new QState(&machine);
s1->addTransition(this, SIGNAL(stateChanged()), s2);
s2->addTransition(this, SIGNAL(stateChanged()), s3);
s3->addTransition(this, SIGNAL(stateChanged()), s1);
connect(s1, SIGNAL(entered()), this, SLOT(runS1())); // these are never triggered
connect(s2, SIGNAL(entered()), this, SLOT(runS2()));
connect(s3, SIGNAL(entered()), this, SLOT(runS3()));
s1->assignProperty(&machine, "state", 1);
s2->assignProperty(&machine, "state", 2);
s3->assignProperty(&machine, "state", 3);
machine.setInitialState(s1);
machine.start();
}
void Test::runS1()
{
qDebug() << "entered state S1";
}
void Test::runS2()
{
qDebug() << "entered state S2";
}
void Test::runS3()
{
qDebug() << "entered state S3";
}
void Test::debugSlot()
{
qDebug() << "slot was triggered!";
}