QThread 不会停止/不处理信号 [英] QThread won't stop / does not process a signal

查看:74
本文介绍了QThread 不会停止/不处理信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在一个单独的线程中执行一些工作,并在工作完成后停止该线程.

I am trying to perform some work in a separate thread and stop that thread when the work is done.

我已经建立了这样的连接

I have set up a connection like this

thread.connect( workerClass, SIGNAL( finished() ), SLOT( quit() ) );

但是当我发出 finished() 信号时,quit() 槽永远不会被调用.命令行不显示任何与失败连接相关的警告.

but the quit() slot is never called when I emit the finished() signal. The command line does not show any warnings related to failed connections.

我创建了一个简单的测试项目来缩小问题的范围,但我得到了相同的行为:

I created a simple test project to narrow down the problem and I get the same behavior:

TestClass.h:

TestClass.h:

#ifndef TESTCLASS_H
#define TESTCLASS_H
class TestClass : public QObject
{
    Q_OBJECT
public:
    TestClass() { }
signals:
    void finished();
public slots:
    void doWork();
}
#endif // TESTCLASS_H

TestClass.cpp:

TestClass.cpp:

#include "TestClass.h"
#include <QtCore/QDebug>
void TestClass::doWork()
{
    qDebug() << "Starting";
    for( long i = 0; i < 1000000000; i++ );
    qDebug() << "Done";
    emit finished();
};

和 main.cpp:

and the main.cpp:

#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include "TestClass.h"

int main( int argc, char* argv[] )
{
    QCoreApplication a( argc, argv );

    TestClass testClass;
    QThread testThread;

    testClass.moveToThread( &testThread );

    testThread.connect( &testClass, SIGNAL( finished() ), SLOT( quit() ) );
    testClass.connect( &testThread, SIGNAL( started() ), SLOT( doWork() ) );

    testThread.start();
    testThread.wait();

    return 0;
}

这就是我期望发生的事情:

So here is what I expected to happen:

  1. 一旦 testThread.start() 被处理,线程的 run() 函数被调用,该函数在内部调用 exec() 并启动一个事件循环.此外,它会抛出一个 started() 信号.
  2. testClass 调用了它的 doWork() 槽.
  3. TestClass::doWork() 完成时,它会抛出一个 finished() 信号.
  4. testThread 的事件循环接收信号并将其转发到它的 quit()
  5. testThread.wait() 在线程结束时从等待中返回.
  1. Once testThread.start() gets processed, the thread's run() function gets called, which internally calls exec() and starts an event loop. Additionally it throws a started() signal.
  2. testClasshas its doWork() slot called.
  3. When TestClass::doWork() is done, it throws a finished() signal.
  4. The event loop of testThread receives the signal and forwards it to its quit() slot
  5. testThread.wait() returns from waiting as the thread has ended.

第 1-3 步工作,我得到 qDebug() 输出.问题出在第 4 步:信号被触发并转发到某个事件循环(我调试了一下,但无法弄清楚它被触发到哪个事件循环)但是 quit()永远不会调用插槽.

Steps 1-3 work and I get the qDebug() output. The problem is at step 4: The signal is fired and forwarded to some event loop (I debugged it a bit, but couldn't figure out to which event loop it was fired) but the quit() slot is never called.

我做错了什么?

P.S.:请不要建议子类化 QThread,我尝试这种方式的全部目的是因为我想避免子类化 QThread.

P.S.: Please don't suggest subclassing QThread instead, the whole point of me trying this way out is because I want to avoid subclassing QThread.

推荐答案

我相信问题在于您实际上没有在场景中运行 Qt 事件循环.如果您将 testThread.wait() 替换为 a.exec()(启动 Qt 事件循环),您应该会看到您的信号/插槽得到正确处理.

I believe the issue is that you actually don't have Qt event loop running in the scenario. If you replace testThread.wait() with a.exec() (which starts the Qt event loop) you should see your signals/slots getting processed properly.

如果您希望应用程序在您的线程完成后退出,您可以使用 QCoreApplication 的 quit() 槽来这样做.

If you want the application to quit when your thread has finished you can use QCoreApplication's quit() slot to do so.

这篇关于QThread 不会停止/不处理信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆