Я хотел бы предисловие, что я очень новичок в программировании. Так что ответ может быть очевиден или я что-то сделал не так; не стесняйтесь (вежливо) указать на это. Мне всегда интересно учиться и становиться лучше!
Я пытаюсь создать и отправить тестовые данные, используя цикл while. Цикл while имеет таймер сна, поэтому данные отправляются только один раз в секунду. Я хотел бы, чтобы кнопка остановки немедленно остановила отправку данных (и отключила кнопку), но из-за таймера сна существует задержка между нажатием кнопки и выполнением функции.
Вот что у меня есть:
void DlgTestData::on_btnStart_clicked()
{
ui->btnStart->setEnabled(false);
ui->btnStop->setEnabled(true);
m_bSendingData = true;
while ( m_bSendingData )
{
CreateAndSendTestData(); //Only sends a single message
QThread::sleep(1`enter code here`)
}
}
void DlgTestData::on_btnStop_clicked()
{
m_bSendingData = false;
ui->btnStart->setEnabled(true);
ui->btnStop->setEnabled(false);
}
Используйте QTimer вместо сна. Таким образом, его можно остановить в любой момент, и он не блокирует другие действия, которые хочет выполнить ваше приложение, пока оно ожидает.
Сделайте QTimer указателем члена вашего класса:
class DlgTestData
{
...
private:
QTimer *m_timer;
};
Затем инициализируйте его в конструкторе:
DlgTestData::DlgTestData()
{
...
// Create, but don't start the timer
m_Timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, &DlgTestData::CreateAndSendTestData);
}
Когда кнопка запуска нажата, просто запустите таймер.
void DlgTestData::on_btnStart_clicked()
{
...
m_timer->start(1000);
}
А затем, когда кнопка остановки нажата, просто остановите таймер.
void DlgTestData::on_btnStop_clicked()
{
...
m_timer.stop();
}
Это прекрасно работает! Спасибо :)
Большой! Я забыл добавить значение тайм-аута к вызову start()
, поэтому внес изменения.
Не рекомендуется иметь операцию блокировки в основном потоке пользовательского интерфейса. Лучше, если вы сначала запустите периодический 1s QTimer, подключите его сигнал к своему
CreateAndSendTestData
, а потом внутриCreateAndSendTestData
поставите дополнительную проверку на флагm_bSendingData
. Это только моя первая идея, конечно, доступно много других решений.