为什么QThread::完成信号没有发出
Why is QThread::finished signal not being emitted?
我创建了自己的TestService
,它在单独的QThread
上运行,但是当MainLoop
终止时,QThread::finished
信号不会发出。我看到了一个类似的问题,但那里的问题略有不同,因为 OP QThread
过载,而我只是将我的类移动到线程上。
请注意,我不重载QThread
类,我只重载QObject
基于以下示例:http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
这是我TestService
课:
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <iostream>
using namespace std;
class TestService: public QObject
{
Q_OBJECT;
private:
volatile int _count;
QWaitCondition _monitor;
QMutex _mutex;
QThread* _thread;
public:
TestService(int numSeconds)
{
_count = numSeconds;
_thread = NULL;
cout << "TestService()" << endl;
}
virtual ~TestService()
{
cout << "~TestService()" << endl;
}
void Start()
{
QMutexLocker locker(&_mutex);
if(_thread == NULL)
{
_thread = new QThread;
// Move this service to a new thread
this->moveToThread(_thread);
// The main loop will be executed when the thread
// signals that it has started.
connect(_thread, SIGNAL(started()), this, SLOT(MainLoop()));
// Make sure that we notify ourselves when the thread
// is finished in order to correctly clean-up the thread.
connect(_thread, SIGNAL(finished()), this, SLOT(OnFinished()));
// The thread will quit when the sercives
// signals that it's finished.
connect(this, SIGNAL(Finished()), _thread, SLOT(quit()));
// The thread will be scheduled for deletion when the
// service signals that it's finished
connect(this, SIGNAL(Finished()), _thread, SLOT(deleteLater()));
// Start the thread
_thread->start();
}
}
void Stop()
{
_count = 0;
_monitor.wakeAll();
}
private slots:
void MainLoop()
{
cout << "MainLoop() Entered" << endl;
while(_count > 0)
{
cout << "T minus " << _count << " seconds." << endl;
QMutexLocker locker(&_mutex);
_monitor.wait(&_mutex, 1000);
_count--;
}
cout << "MainLoop() Finished" << endl;
emit Finished();
}
virtual void OnFinished()
{
cout << "OnFinished()" << endl;
}
signals:
void Finished();
};
以下是测试代码:
void ServiceTest()
{
cout << "Press q to quit." << endl;
cout << "Press s to start." << endl;
cout << "Press t to stop." << endl;
QSharedPointer<TestService> testService(new TestService(10));
char in = 'a';
while( in != 'q' )
{
switch(tolower(in))
{
case 's':
testService->Start();
break;
case 't':
testService->Stop();
break;
default:
break;
}
cin.get(in);
in = tolower(in);
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ServiceTest();
QTimer::singleShot(0, &a, SLOT(quit()));
return a.exec();
}
输出为:
Press q to quit.
Press s to start.
Press t to stop.
TestService()
s
MainLoop() Entered
T minus 10 seconds.
T minus 9 seconds.
T minus 8 seconds.
t
MainLoop() Finished
q
~TestService()
Press any key to continue . . .
谁能解释为什么finished
没有发出我该如何解决它?
信号 done() 被发出原因,但你没有抓住它。
这里:
connect(_thread, SIGNAL(finished()), this, SLOT(OnFinished()));
使用Qt::QueuedConnection
,因为_thread
和this
(服务)位于不同的线程中。
当finished()
发出时,_thread
的事件循环已经执行完毕,因此信号不会传递到插槽。
您可以显式使用 Qt::DirectConnection
。
编辑:
QTherad的工作原理是这样的:
QThread::start()
{
emit started();
run();
emit finished();
}
QThread::run()
{
eventloop->exec();
}
因此,当发出finished
时,事件循环已经停止执行。当你service
移动到_thread
时,服务的事件循环_thread
事件循环。
请注意,QObject
本身没有自己的事件循环。事件循环由对话框、线程和应用程序创建。
实际上,在您的简单情况下,我建议只使用QtConcurent::run
,因为您不会在新线程中执行实际的事件处理,而只是运行单个函数。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 为什么我不能调用 QMetaObject::invokeMethod(&threadObj, &QThread::start, Qt::QueuedConnection)?
- 为什么QThread::完成信号没有发出
- 我不确定为什么我的 QThread 模式被阻塞