我决定使用信号来表示线程的完成。如果仍有更多工作,我将信号连接到重新启动过程的代码。唉,连接到信号的代码永远不会触发。这让我很伤心。
我需要知道为什么下面的代码块中的'Tester'方法不会触发。
我是python的新手,所以当我开始写这篇文章时,我研究了信号并在tgray发布here的解决方案之后对代码进行了建模,显然我错过了一些重要的东西,但我真的很可以'看看它是什么。
以下是我的代码的大规模简化版本:
from PyQt4.QtCore import *
import time
class Worker(QThread):
__pyqtSignals__ = ( "a",
"b" )
def __init__(self):
QThread.__init__(self, None)
def run(self):
print "'Worker.run' starts"
self.emit(SIGNAL("a"))
print "'Worker.run' ends"
class Main:
def Do(self):
print "'Do' starts"
self.Launch()
time.sleep(2)
print "'Do' ends"
def Launch(self):
print "'Launch' starts"
self.worker = Worker()
QObject.connect(self.worker, SIGNAL("a"), self.Tester)
self.worker.daemon = True
self.worker.start()
print "'Launch' ends"
def Tester(self):
print "Tester Fired!!"
m=Main()
运行:
>>> m.Do()
收率:
'Do' starts
'Launch' starts
'Launch' ends
'Do' ends
'Worker.run' starts
'Worker.run' ends
但不是预期的:
Tester Fired!!
我错过了什么?另外,为什么“Worker.run”中的打印出现在其他所有内容之后,即使使用sleep(2)
?
答案 0 :(得分:3)
如果您想要查看回调,则必须更改连接方式 您的QThread信号到您的插槽:
QtCore.QObject.connect(self.worker,
Qt.SIGNAL("a"),
self.Tester,
Qt.Qt.DirectConnection) #this is added
<强>说明:强> 自Qt 4以来,Qt信号/插槽是线程安全的。文档说明了正常行为 将信号连接到插槽是'AutoConnection',这意味着它是直接的(回调是 如果信号和插槽都在同一个线程中,则在发射后立即触发) 如果信号是从另一个线程(您的情况)发出的,则排队。
然后,必须处理这个队列:通常,这是在应用程序运行时由Qt循环完成的。
信号“排队”的事实意味着控制转移到Qt循环 确保即使信号来自另一个,也会在主线程中调用回调 线程。
在你的问题代码中,根本没有事件循环 - 所以获得你的问题的唯一方法 从另一个线程调用的插槽是改变调度信号的方式。不要用 但是,在你的代码中,因为在正常的应用程序中你运行了Qt循环, 它本来可以正确发送(并安全地从线程问题)。