首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PyQt QThread中使用moveToThread()方法的等待()问题

PyQt QThread中使用moveToThread()方法的等待()问题
EN

Stack Overflow用户
提问于 2022-11-13 02:40:29
回答 1查看 44关注 0票数 0

我试图用QThread在PyQt6中编写一个多线程程序。

示例代码如下所示。

我使用moveToThread()方法创建了两个线程,并期望在完成后将它们连接起来,但是结果是压倒性的。

我知道另一种方法是创建QThread的子类,编写起来更容易,但我仍然想了解为什么moveToThread()不能这样做。

谢谢!

代码语言:javascript
运行
复制
import sys
import logging
from functools import partial
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *

logging.basicConfig(format="%(message)s", level=logging.INFO)

class MyWork(QObject):
  finished = pyqtSignal()
  def run_work(self, obj_name):
    # sleep 3 secs and finish
    for i in range(3):
      QThread.sleep(1)
      logging.info(f'{obj_name}: {i} sec.')
    self.finished.emit()

class MyWindow(QWidget):
  def __init__(self):
    super().__init__()
    self.setWindowTitle('MyWork Example')

app = QApplication(sys.argv)
form = MyWindow()
form.show()

# create two threads
th1 = QThread()
wo1 = MyWork()
wo1.moveToThread(th1)
th1.started.connect(partial(wo1.run_work, 'obj1'))
wo1.finished.connect(th1.quit)
th1.start()

th2 = QThread()
wo2 = MyWork()
wo2.moveToThread(th2)
th2.started.connect(partial(wo2.run_work, 'obj2'))
wo2.finished.connect(th2.quit)
th2.start()

# join two threads and finish
th1.wait()
th2.wait()
logging.info('All threads finished.')

sys.exit(app.exec())

产出:

代码语言:javascript
运行
复制
obj1: 0 sec.
obj2: 0 sec.
obj2: 1 sec.
obj1: 1 sec.
obj2: 2 sec.
obj1: 2 sec.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-13 16:42:51

你所看到的是由这样一个事实引起的,即跨线程信号在接收器的线程中调用它们连接的函数。

请记住,QThread (就像python中的线程对象一样)不是“线程”,而是访问和运行它的接口。

当你这样做时:

代码语言:javascript
运行
复制
wo1.finished.connect(th1.quit)

结果是,quit()将在创建th1的线程中调用,该线程是主线程。

由于wait()阻塞了调用它的线程的事件循环,所以对quit()的调用是排队的,从未处理过。

对于这种特殊情况,解决方案是对信号使用直接连接:

代码语言:javascript
运行
复制
wo1.finished.connect(th1.quit, Qt.DirectConnection)
# ...
wo2.finished.connect(th2.quit, Qt.DirectConnection)

通过这样做,将从实际线程调用quit(),从而允许它立即进行处理。

请注意,您的是一个非常特殊的情况,通常不会被使用。通常,您将工作人员“已完成”信号连接到quit()wait() (按此特定顺序),或者在实际需要退出时按相同顺序调用这些函数,或者将QThread finished信号连接到最终将打印线程执行完成的函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74418100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档