Как остановить фоновый цикл после нажатия кнопки?

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

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

void start()
{
for (size_t i=0, i<10000000; ++i)
{
// do some computing
QApplication::processEvents(); // Else clicking the stop button has no effect until the end of the loop
if (m_stop) break; // member m_stop set to false at start.
}
}

Итак, когда я нажимаю кнопку остановки, он запускает слот

void stopLoop()
{
m_stop = true;
}

Проблема с этим методом заключается в том, что processEvents() слишком сильно замедляет время выполнения .. Но, может быть, это неизбежно ..

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

Или сигналы и слоты или нет, может, у кого-то есть лучший способ добиться этого?

РЕДАКТИРОВАТЬ

Следуя этому совету, у меня теперь есть сценарий рабочий / поток. Так у меня в окне конструктор

Worker *worker;
QThread *thread ;
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(work()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();

Который, кажется, работает нормально. Но как я мог представить QTimer сейчас ?

Должен ли я подключить QTimer в нить start() функция

connect(timer, &QTimer::timeout, thread, &QThread::start);

Или я должен подключить поток к QTimer«s start() функция?

connect(thread, SIGNAL(started()), timer, &QTimer::start());

Или нет … но тогда как?

2

Решение

используйте QTimer

void start()
{
this->timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyObject::work);
connect(stopbutton, &QButton::clicked, timer, &QTimer::stop);
connect(stopbutton, &QButton::clicked, timer, &QTimer::deleteLater);
connect(this, &MyObject::stopTimer, timer, &QTimer::deleteLater);
connect(this, &MyObject::stopTimer, timer, &QTimer::stop);
timer->setInterval(0);
timer->setSingleShot(false);
timer->start();

}

void work()
{
//do some work and return

if (done)emit stopTimer();
}
2

Другие решения

Одна вещь, которую вы могли бы сделать, чтобы быть менее «блочной» — это выполнять свою работу в рабочем потоке, используя QThread, Тогда замедление не будет такой большой проблемой, в то время как вы все равно сможете изящно прекратить работу.

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

1

По вопросам рекламы [email protected]