调用 moveToThread() 方法后,我可以从主线程调用 QObject 方法吗?

问题描述 投票:0回答:1

我有工人阶级

class Worker(QObject):
    finished = Signal()

    def __init__(self, n):
        super().__init__()
        self.a_flag = False
        # self.mutex = QMutex()

    # @Slot()
    def stop(self):
        self.a_flag = True

    @Slot()
    def do_work(self):
        while True:
            if self.a_flag:
                break
            # do some wo
        self.finished.emit()

在控制器的某个地方(从主线程)我将其移动到新线程

self.worker = Worker(num)
self.worker_thread = QThread()
self.worker.moveToThread(self.worker_thread)

self.worker.moveToThread(self.worker_thread)
之后,
worker
的线程亲和力发生了变化,我想我无法访问控制器中
worker
的成员(我不确定,但我可以争论为什么)。有没有相关的参考资料?

在控制器(主线程)中的某处执行

self.a_flag = True
或调用
stop()
是否安全?

有什么解决方法可以通知

do_work
退出循环吗?

python qt pyqt pyside qthread
1个回答
0
投票

在调用

QObject
方法后,我可以从主线程调用
moveToThread()
方法吗?

是的。

我在 Qt 文档中找到了支持这一说法的内容

如果您正在调用不在当前线程中的

QObject
子类上的函数 [...]

这表明使用

QObject
将此对象移动到另一个线程后,从主线程访问
moveToThread()
子类的成员是有效的。


现在来说第二个问题:

有什么解决方法可以通知

do_work
退出循环吗?

是的。

要么

  1. 从主线程调用

    stop()

  2. 在主线程中设置

    worker.a_flag
    。 (感谢 @musicamante@ekhumoro 的宝贵意见)。我们可以在主线程中设置
    worker.a_flag
    的原因

    • a_flag
      是一个boolean,设置它是Python中的原子操作。这使得它线程安全并且可以在主线程中设置
    • a_flag
      始终由一个线程(主线程)设置并由另一个线程读取。

请注意,如果

a_flag
也由辅助线程设置,则此操作不是线程安全的。在这种情况下就需要互斥锁。 (更多信息这里]

另请注意,如有疑问,请使用互斥体

def __init__(self, n):
    super().__init__()
    self.a_flag = False
    self.mutex = QMutex()

def stop(self):
    self.mutex.lock()
    self.a_flag = True
    self.mutex.unlock()

在我看来,在这里获取锁不会带来太多开销。

© www.soinside.com 2019 - 2024. All rights reserved.