QTimer не срабатывает при втором вызове - PullRequest
0 голосов
/ 07 февраля 2011

Я реализовал шаблон состояния в qt.Внутри моей функции EnterIdleState я подключаю таймер одиночной съемки, чтобы начать работу.При первом вызове это работает нормально, со второй попытки, однако таймер не срабатывает, хотя соединение устанавливается, как и раньше:

Кодовый поток выглядит следующим образом:

SetNewState(newIdleState());
IdleState::doWork();
SetNewState(new WorkState());
WorkdState::doWork();
SetNewState(newIdleState());

SetNewStateвыглядит так:

void IridiumProcessor::SetNewState(State* pNewState)
{
    if (m_pCurrentState)
    {             
        m_pCurrentState->LeaveState();
        delete m_pCurrentState;
    }    
    m_pCurrentState = pNewState;
    if (m_pCurrentState)
        m_pCurrentState->EnterState();
}

При входе в IdleState я подключаю таймер одиночного выстрела:

void IdleState::EnterState()
{
    QTimer::singleShot(1000,this,SLOT(OnTimeout())); 
}
void IdleState::OnTimeout()
{
    qDebug() << "IdleState OnTimeout";
}

То же самое происходит, когда я использую membervar QTimer вместо статического вызова singleShot.

Ответы [ 2 ]

1 голос
/ 07 февраля 2011

Я вижу только несколько возможных причин для этого, за исключением действительно серьезных ошибок, таких как повреждение памяти и тому подобное.

Возможно, вы вызываете свой метод EnterState () до истечения времени ожидания. Второй вызов отменяет предыдущий и повторяется снова и снова. Чтобы отладить это, вы должны добавить выходные данные отладки в метод EnterState (), желательно со временем, чтобы увидеть, действительно ли это происходит. Если нет, значит, я здесь не прав.

Также может случиться так, что вы уничтожите приемник до того, как сигнал будет излучен, как предположил Халуп.

Другая возможность заключается в том, что вы блокируете поток событий с помощью некоторой длительной операции. Таймер не сработает, пока элемент управления не вернется в цикл событий Qt потока, в котором живет таймер. В случае однопоточного приложения это цикл основного события.

0 голосов
/ 07 февраля 2011

Я бы добавил логи в деструкторы IdleState: может быть, вы уничтожите их в IridiumProcessor :: SetNewState до истечения времени ожидания QTimer?

Также рассмотрите возможность использования QStateMachine вместо написания собственного решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...