Я использовал эту функцию в моей программе:
void delay(QState * state1, int millisecond, QAbstractState * state2)
{
auto timer = new QTimer(state1);
timer->setSingleShot(true);
timer->setInterval(millisecond);
QObject::connect(state1, &QState::entered, timer, static_cast<void (QTimer::*)()>(&QTimer::start));
QObject::connect(state1, &QState::exited, timer, &QTimer::stop);
state1 -> addTransition(timer, SIGNAL(timeout()), state2);
}
Я сделал копию вставки из примера, и я не понял эту часть кода:
QObject::connect(state1,..., static_cast<void (QTimer::*)()>(&QTimer::start));
Кто-нибудь может объяснить мне, что это за код? Как это работает в программе?
PS. Я пытался изменить этот код с этим, но это не сработало:
QTimer *timer = new QTimer(state1);
.
. //same code as before
.
QObject::connect(stato1,&QState::entered,timer,[&] {timer->start();} );
QObject::connect(stato1,&QState::exited, timer,[&] {timer->stop(); } );
stato1 -> addTransition(timer,SIGNAL(timeout()),stato2);
Есть два QTimer::start
игровые автоматы, один без параметров и один с int msec
параметр. Чтобы подключиться к правильному с новым синтаксисом подключения, вы должны указать тип слота с помощью static_cast
,
Итак, в этой строке:
QObject::connect(state1, &QState::entered, timer, static_cast<void (QTimer::*)()>(&QTimer::start));
Вы подключаетесь к QTimer::start
слот, который не принимает аргументов.
Если у вас был сигнал с int
параметр, и вы хотите подключиться к QTimer::start(int msec)
Слот, вы бы сделали это так:
connect(this, &MyClass::mySignal, timer, static_cast<void (QTimer::*)(int)>(&QTimer::start));
Вы можете прочитать больше об использовании перегруженных сигналов / слотов с новым синтаксисом подключения Вот.
Вы также можете использовать qOverload
убрать необходимость уродливых static_cast
,
Во фрагменте, где вы используете лямбда-выражения, вы фиксируете timer
по ссылке. Вы должны захватить это значение вместо этого:
QObject::connect(stato1, &QState::entered, timer, [=]{timer->start();});
Других решений пока нет …