I was trying to use the similar way that Kuba has done in post here. Basically I want to construct a overridden StatefulObject programatically using
void Command::buildStatefulCommands(DeviceComm* dev, COMMAND_TYPE cmdtype, const QAbstractProxyModel* entries)
{
// according to cmdtype and number of entries, build the transition mapping dynamically
....
switch (cmdtype) {
case CMDUploadEntries: {
    connectSignals();  // the same as in example
    send  (&s_start, dev, QByteArray::fromHex(entries.at(index,0))); // 'dev' changed to use my own DeviceComm for communication, 
    expect(&s_start, dev, QByteArray::fromHex(entries.at(index,1)), &s_ok_01, 3000, &s_failed);
    expect(&s_start, dev, QByteArray::fromHex(entries.at(index,2)), &s_ok_02, 3000, &s_failed);
....
}
The state transition building process of StatefulObject will be called everytime a button is clicked (because the data to send might be changed)
void MainWindow::on_btnSend_clicked(){
....
// the cmdtype is used for different tasks
Command* cmd = Command::getCommand(cmdtype);
    cmd->buildStatefulCommands(m_commDev, cmdtype, getDatabase());
   
    if (cmd->isRunning())
        cmd->stop();
    cmd->start();
}
Question 1. As the setup of statemachine is done multiple times, how to disconnect the old signal/slot pair? I guess every time 'send' invocation will cause a new lambda anonymous functor be created due to the capture.
void send(QAbstractState * src, QIODevice * dev, const QByteArray & data) {
// how to disconnect the previous connect?
conn = 
    QObject::connect(src, &QState::entered, dev, [dev, data]{
  dev->write(data);
     });
}
The second related question, instead of using 'readyRead' signal as in original 'expect' while adding transition
void expect(QState * src, QIODevice * dev, const QByteArray & pattern, QAbstractState * dst,
        int timeout = 0, QAbstractState * dstTimeout = nullptr)
{
   addTransition(src, dst, dev, SIGNAL(readyRead()), [dev, pattern]{
      return hasLine(dev, data);
   });
   if (timeout) delay(src, timeout, dstTimeout);
}
how can I use a signal 'responsePosted' that has argument (say, 'payload') to be connected with lambda that still has capture list (i.e. the pattern to check with)? I tried to use auto to cast into function pointer, but not supported with capture in it.
Q_SIGNALS:  // 'dev' signals
    void responsePosted(const QByteArray& payload);
....
// I want to have different pattern to check with while building the state transition table
addTransition(src, dst, dev, SIGNAL(responsePosted()), [dev, pattern](const QByteArray& payload){
  return dev->matching(payload, pattern);
 });
The template functor in GuardedSignalTransition for 'eventTest' does not seem to take any argument. How to wrap it with argument?
template <typename F>
class GuardedSignalTransition : public QSignalTransition {
   F m_guard;
   QByteArray m_pattern;   // << I want to store the pattern here
protected:
   bool eventTest(QEvent * ev) Q_DECL_OVERRIDE {
      return QSignalTransition::eventTest(ev) && m_guard();  // <<<< I guess 'ev' has the passed-in argument ?
   }
template <typename F> static GuardedSignalTransition<F> *
addTransition(QState * src, QAbstractState *target,
              const QObject * sender, const char * signal, F && guard) {  // What function type will F be?
   auto t = new GuardedSignalTransition<typename std::decay<F>::type>
         (sender, signal, std::forward<F>(guard));  // what should I put here ?
   t->setTargetState(target);
   src->addTransition(t);
   return t;
}
The std::forward, std::move, && annotation and std::decay are difficult to understand.