Reputation: 149
In my program, I open a window and run a big loop. I display progress in a QTextEdit
. I added a cancel button to stop the big loop.
So in the window constructor I run a method that looks like,
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.
}
}
So, when I click the stop button, it runs the slot
void stopLoop()
{
m_stop = true;
}
The problem with that method is that processEvents()
slows the execution time a little too much.. But maybe it's inevitable ..
I wanted to try it with signals and slots, but I can't seem to think of how I could connect the pushed stop button with the loop.
Or, signals and slots or not, maybe someone has a better way of achieving this ?
EDIT
Following this thread advice, I now have a worker/thread scenario. So I have in a window constructor
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();
Which seems to work fine. But how could I introduce a QTimer
now ?
Should I connect the QTimer
to the thread's start()
function
connect(timer, &QTimer::timeout, thread, &QThread::start);
Or, should I connect the thread to the QTimer
's start()
function ?
connect(thread, SIGNAL(started()), timer, &QTimer::start());
Or neither ... but then, how ?
Upvotes: 2
Views: 601
Reputation: 53175
One thing that you could do to be less "blocky" is to do your work in a worker thread using QThread
. Then, the slow-down would not it be such a big problem anymore while you would still be able to gracefully terminate the work.
I would also reconsider this large number iteration in favor of a QTimer
. Then, basically the cancel button or the timer's timeout would trigger the worker loop to break. In that case, the while condition for the iteration would be the m_stop
guard.
Upvotes: 1
Reputation: 48216
use a 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();
}
Upvotes: 2