QThread finished() signal is never emited

我与影子孤独终老i 提交于 2020-01-02 16:42:32

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!