3 回答
TA贡献1951条经验 获得超3个赞
无论是在将worker对象移动到另一个线程之前还是之后进行连接都无关紧要。引用Qt文档:
Qt :: AutoConnection - 如果信号是从与接收对象不同的线程发出的,则信号排队,表现为 Qt :: QueuedConnection。否则,直接调用插槽,表现为Qt :: DirectConnection。发射信号时确定连接类型。[强调补充]
因此,只要type
参数connect
设置为QtCore.Qt.AutoConnection
(默认值),Qt应确保以适当的方式发出信号。
示例代码的问题更可能是使用插槽而不是信号。信号连接的python方法可能需要使用pyqtSlot装饰器标记为Qt插槽:
from QtCore import pyqtSlotclass Scanner(QObject): @pyqtSlot() def scan(self): scan_value(start, stop, step) progress.setValue(100)
编辑:
应该澄清的是,只有在相当新版本的Qt中,才会在发出信号时确定连接类型。在4.4版本中引入了此行为(以及Qt的多线程支持中的其他一些更改)。
此外,可能值得进一步扩展PyQt特定问题。在PyQt中,信号可以连接到Qt插槽,另一个信号或任何python可调用。对于后一种情况,在内部创建一个代理对象,它包装python可调用并提供Qt信号/插槽机制所需的插槽。
正是这个代理对象才是问题的原因。一旦创建了代理,PyQt就会这样做:
if (rx_qobj) proxy->moveToThread(rx_qobj->thread());
如果在将接收对象移动到其线程之后建立连接,那么这很好; 但如果是之前的代理,代理将保留在主线程中。
使用@pyqtSlot
装饰器可以完全避免这个问题,因为它可以更直接地创建Qt插槽,并且根本不使用代理对象。
最后,还应该注意到这个问题目前不会影响PySide。
TA贡献1816条经验 获得超4个赞
我的问题是通过movinf连接到初始化工作线程的地点来解决的,在我的情况下,因为我正在访问一个对象,该对象仅在我的Worker Object类实例化后才存在于另一个线程中。
只需连接后的信号 self.createWorkerThread()
添加回答
举报