QThread finished()信号永远不会发出

sap*_*sap 2 c++ qt qthread

所以我有一个有2个插槽的工作类:StartWork()和StopWork(),StartWork()运行一个无限循环(它只是读取和读取摄像头输入不停),StopWork()方法只是设置一个bool变量为false(因此StartWork()内的循环停止).

根据QThread文档,现在使用它们的最佳方法不是通过子类化,而是通过将工作者移动到线程中,这就是我所做的.问题是,来自线程的started()信号被调用,但是完成的()信号永远不会被调用.

工人类槽:

void StartWork(){running = true; 而(跑步){做工; }}

void StopWork(){running = false; }

QThread初始化和信号/插槽连接:

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()));
Run Code Online (Sandbox Code Playgroud)

在我的QPushButton上,我这样做:

if(pushStartStop->text().toLower() == "start")
{
    pushStartStop->setText("Stop");
    thread->start();
}
else
{
    pushStartStop->setText("Start");
    thread->quit();
}
Run Code Online (Sandbox Code Playgroud)

thread-> start()工作正常,StartWork()被调用,一切都很漂亮(GUI运行没有块等).

但是thread-> quit()没有做任何事情,它被调用(因为按钮改变文本),但就是这样.如果我只是调用worker-> StopWork()它可以工作,但我不能再启动它.

我尝试过thread-> exit(); 但结果是一样的.我也知道子类分类工作,但它看起来更丑陋,根据最近的Qt文档,子分类不再是最佳的.

提前致谢.

Syn*_*xis 5

你有一个永远的循环:

void StartWork()
{
    running = true;
    while(running)
    {
        do work;
    }
}
Run Code Online (Sandbox Code Playgroud)

此函数将循环,因此线程的事件循环在发出后立即被阻止started().因此,finished()不能发射.

解决方案1:

添加功能

void DoWork()
{
    if(running)
    {
        do work
    }
}
Run Code Online (Sandbox Code Playgroud)

对工人而言,改变

void StartWork()
{
    running = true;
}
Run Code Online (Sandbox Code Playgroud)

然后,只需连接DoWork到线程中的计时器.

解决方案2:

改变功能

void StartWork()
{
    running = true;
    while(running)
    {
        do work;
        QCoreApplication::processEvents();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,您将不得不在工作程序停止其作业时重新启动线程(StopWork()将强制此函数完成,因此事件循环将没有要处理的事件并且线程将完成).