gpt4 book ai didi

c++ - 如何退出 worker QThread 的事件循环

转载 作者:行者123 更新时间:2023-11-30 01:43:28 26 4
gpt4 key购买 nike

我正在编写一个带有按钮的应用程序来启动/停止工作线程(它实现了QThread)。工作线程每隔几毫秒就会持续调度一个作业。要终止工作线程,我从 GUI 线程调用 worker.quit()(worker.exit(0) 也不起作用)方法并等待finished 信号被触发。

问题是即使触发了 finished 信号,线程也没有终止。

这是一个最小的例子: https://gist.github.com/NawfelBgh/941babdc011f07aa4ab61570d7b88f08

screenshot of the minimal example

编辑

我对发生的事情的解释是错误的:工作线程正在终止但是方法 iter 正在主线程中执行,正如@sergey-tachenov 所说的和从使用代码生成的日志中确认:

void run() {
std::cout <<"From worker thread: "<<QThread::currentThreadId() << std::endl;
...
void iter() {
std::cout <<"From thread: "<<QThread::currentThreadId() << std::endl;
...
void MainWindow::on_pushButton_clicked()
{
std::cout <<"From main thread: "<<QThread::currentThreadId() << std::endl;

我切换到 different design它不依赖于 QTimer。但是我没有将它作为答案提交,因为这个问题的标题是“如何退出 worker QThread 的事件循环”。

最佳答案

线程终止。只有你的计时器不在你启动的线程中运行,而是在主线程中运行,这就是它没有停止的原因。这是因为它默认使用排队连接,并且线程对象存在于创建它的线程中,即主线程。要修复它:

  • 不要子类QThread。这通常不是一个好主意,除非您想实际扩展 QThread 的功能。
  • 创建一个继承 QObject 的独立工作对象。
  • 使用moveToThread 将工作对象移动到创建的线程。它会导致它的所有插槽实际在线程中触发。如果您使用默认或排队的连接,那就是。

The QThread docs提供一个很好的例子(第一个)。

请注意,如果您真的想使用线程提供的数据来更新 GUI,则必须以某种方式将该数据正确发布到 GUI 线程(可能使用 emit 和排队连接)尝试直接从线程更新 GUI。如果您想访问共享数据,您可能需要使用 QMutex 来保护它,而不是像您使用共享计数器那样。

关于c++ - 如何退出 worker QThread 的事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37755086/

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