我试图在一个单独的线程中执行一些工作,并在工作完成后停止该线程.
我已经建立了这样的连接
thread.connect( workerClass, SIGNAL( finished() ), SLOT( quit() ) );
Run Code Online (Sandbox Code Playgroud)
但是当我发出finished()信号时,从不调用quit()槽.命令行不显示与失败连接相关的任何警告.
我创建了一个简单的测试项目来缩小问题范围,我得到了同样的行为:
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
Run Code Online (Sandbox Code Playgroud)
TestClass.cpp:
#include "TestClass.h"
#include <QtCore/QDebug>
void TestClass::doWork()
{
qDebug() << "Starting";
for( long i = 0; i < 1000000000; i++ );
qDebug() << "Done";
emit finished();
};
Run Code Online (Sandbox Code Playgroud)
和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;
}
Run Code Online (Sandbox Code Playgroud)
所以这就是我期望发生的事情:
testThread.start()被处理,线程的run()函数就会被调用,它会在内部调用exec()并启动一个事件循环.此外它还会发出started()信号.testClass有它的doWork()插槽叫.TestClass::doWork()完成时,它抛出一个finished()信号.testThread接收信号并将其转发到其quit()插槽testThread.wait() 线程结束时从等待返回.步骤1-3工作,我得到qDebug()输出.问题出在第4步:信号被触发并转发到某个事件循环(我稍微调试了一下,但无法弄清楚它被触发了哪个事件循环)但是quit()从不调用插槽.
我究竟做错了什么?
PS:请不要建议继承QThread,我尝试这种方式的全部意义是因为我想避免继承QThread.
我认为问题是你实际上没有在场景中运行Qt事件循环.如果替换testThread.wait()为a.exec()(启动Qt事件循环),您应该看到您的信号/插槽得到正确处理.
如果您希望应用程序在线程完成后退出,则可以使用QCoreApplication的quit()插槽来执行此操作.
| 归档时间: |
|
| 查看次数: |
3402 次 |
| 最近记录: |