问题
so i have a worker class that has 2 slots: StartWork() and StopWork(), the StartWork() one runs an infinite loop (it just reads and reads camera input non-stop) and the StopWork() method just sets a bool variable to false (so the loop inside StartWork() stops).
according to the QThread documentation, the best way to use them now is not by sub-classing but by moving workers into the thread, so that's what i do. problem is, the started() signal from the thread gets called but the finished() signal never gets called.
worker class slots:
void StartWork(){ running = true; while(running){ do work; }}
void StopWork(){ running = false; }
QThread initialization and signal/slot connection:
thread = new QThread();
worker = new Worker();
worker.moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(StartWork()));
QObject::connect(thread, SIGNAL(finished()), worker, SLOT(StopWork()));
and on my QPushButton i do this:
if(pushStartStop->text().toLower() == "start")
{
pushStartStop->setText("Stop");
thread->start();
}
else
{
pushStartStop->setText("Start");
thread->quit();
}
the thread->start() works fine, and the StartWork() gets called and everything is beautiful (GUI runs with no blocks, etc).
but thread->quit() doesn't do anything, it gets called (because the button changes text) but thats it. if i just call worker->StopWork() it works, but then i can't start it again.
I've tried with thread->exit(); but the results are the same. Also i know sub-classing works, but it looks uglier and according to the recent Qt documentation, sub-classing is no longer optimal.
thanks in advance.
回答1:
You have a forever loop:
void StartWork()
{
running = true;
while(running)
{
do work;
}
}
This function will loop, so the event loop of the thread is blocked just after having emitted started()
. Thus, finished()
cannot be emitted.
Solution 1:
Add the function
void DoWork()
{
if(running)
{
do work
}
}
To Worker, and change
void StartWork()
{
running = true;
}
Then, just connect DoWork
to a timer in the thread.
Solution 2:
Change the function
void StartWork()
{
running = true;
while(running)
{
do work;
QCoreApplication::processEvents();
}
}
With this solution, you will have to restart the thread when the worker stops its job (StopWork()
will force this function to finish, so the event loop will have no events to handle and the thread will be finished).
来源:https://stackoverflow.com/questions/12942461/qthread-finished-signal-is-never-emited