Hi,

I am trying to implement camera acquisition class with OpenCV and QStateMachine.
I have the following state machine definition:

Qt Code:
  1. DriverVideoCapture::DriverVideoCapture(QObject *parent, const int camid) : QObject(parent)
  2. {
  3. // configure state machine
  4. m_engine = new QStateMachine(this);
  5. QState *state_idle = new QState(m_engine);
  6. QState *state_acquire = new QState(m_engine);
  7. QState *state_error = new QState(m_engine);
  8.  
  9. state_idle->addTransition(this, &DriverVideoCapture::start, state_acquire);
  10. state_idle->addTransition(this, &DriverVideoCapture::error, state_error);
  11. state_acquire->addTransition(this, &DriverVideoCapture::grab, state_acquire);
  12. state_acquire->addTransition(this, &DriverVideoCapture::stop, state_idle);
  13. state_acquire->addTransition(this, &DriverVideoCapture::error, state_error);
  14. connect(state_acquire, &QState::entered, this, &DriverVideoCapture::on_stateAcquire);
  15. m_engine->setInitialState(state_idle);
  16. m_engine->start();
  17.  
  18. m_videoCapture = new cv::VideoCapture(camid);
  19. if (!m_videoCapture->isOpened())
  20. emit error();
  21. }
To copy to clipboard, switch view to plain text mode 

Now inside state_acquire I will do the blocking operation of frame reading

Qt Code:
  1. void DriverVideoCapture::on_stateAcquire()
  2. {
  3. cv::Mat frame;
  4. if (!m_videoCapture->isOpened())
  5. return;
  6.  
  7. if (!m_videoCapture->read(frame))
  8. emit error();
  9.  
  10. emit grab();
  11. }
To copy to clipboard, switch view to plain text mode 

And I will connect buttons to start and stop the process:

Qt Code:
  1. m_driverVideoCapture = new DriverVideoCapture(this);
  2. connect(ui->pushButton_start, &QPushButton::clicked, m_driverVideoCapture, &DriverVideoCapture::start);
  3. connect(ui->pushButton_stop, &QPushButton::clicked, m_driverVideoCapture, &DriverVideoCapture::stop);
To copy to clipboard, switch view to plain text mode 

The state machine get's a transition from state_idle to state_acquire after the start signal. Then it continues looping inside state_acquire. Once the stop signal is emitted though, it does not get detected and the state machine fails to do the transition from state_acquire to state_idle again. Any clues?

Second question, the event loop created by QStateMachine should be in the current thread. If I move the DriverVideoCapture to a worker thread, as in http://doc.qt.io/qt-4.8/QThread, is the state machine getting an event loop different from the main GUI event loop?

Thank you in advance for any clarifications and tips!