gpt4 book ai didi

c++ - 为什么我的信号在没有 Qt::DirectConnection 的情况下不能触发插槽?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:11:59 25 4
gpt4 key购买 nike

我有一个主类启动一个执行单个操作的线程。我正试图捕捉线程操作何时完成。

主类:

// .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() Action 怎么办呢?

编辑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()));

站点节点 - 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()));
}

关于c++ - 为什么我的信号在没有 Qt::DirectConnection 的情况下不能触发插槽?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39910644/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com