为什么我的信号不触发没有Qt::D irectConnection的插槽?
Why don't my signals fire slots without Qt::DirectConnection?
我有一个主类,它启动一个执行单个操作的线程。我正在尝试捕捉线程操作何时完成。
主类:
// .h
class MainClass : public QObject
{
Q_OBJECT
public:
QThread thread;
// ...
public slots:
void onFinish();
}
// .cpp
void MainClass::startThread()
{
thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(worker, SIGNAL(finished()), this, SLOT(onFinish()));
// connect(worker, SIGNAL(finished()), this, SLOT(onFinish()), Qt::DirectConnection);
}
void MainClass::onFinish()
{
std::cout << "Finished!" << std::endl << std::flush;
}
线程的Worker
类:
// .h
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
~Worker();
public slots:
void process();
signals:
void finished();
}
// .cpp
void Worker::process()
{
// ...Do stuff...
emit finished();
}
执行startThread
不打印"Finished!"为什么?
我注意到,如果我将Qt::DirectConnection
添加到连接到onFinish()
的行(如在注释行中),则打印消息。但是,如果我想在主类的线程中执行onFinish()
动作,我能做些什么呢?
编辑1
此外,似乎finished()
-> quit()
连接也不起作用,因为如果我调用thread->isFinished()
或thread->isRunning()
,在主线程睡眠后确保线程任务完成,我分别获得false
和true
。
编辑2
因为它也可能是相关的,这里是main.cpp:
int _tmain(int argc, _TCHAR* argv[])
{
QCoreApplication a(argc, argv);
std::unique_ptr <MainClass> mc = std::make_unique <MainClass>();
mc->startThread();
mc->thread->wait();
return a.exec();
}
乍一看,我觉得连接的顺序很重要。deleteLater()
插槽应该总是最后一个方法。
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), this, SLOT(onFinish()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
Sitenode - QRunnable您可以考虑使用QRunnable,它是为短时间运行的任务/作业而设计的。您可以将它们与QObject或QFuture/QFutureWatcher组合在一起,以便在它们完成时获得通知。
<标题>更新1你的主事件循环永远不会开始,看起来你想在任务完成时退出应用程序。我不认为这是一个很好的实现,但这些修改应该为您工作:
int _tmain(int argc, _TCHAR* argv[])
{
QCoreApplication a(argc, argv);
std::unique_ptr<MainClass> mc = std::make_unique<MainClass>();
mc->startThread();
// do not wait!
// let the main-event-loop handle events -> a.exec()
// and quit() application by signal/slot
return a.exec();
}
void MainClass::startThread()
{
thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), this, SLOT(onFinish()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), qApp, SLOT(quit()));
}
标题>