自定义信号和多线程
Custom signals and multithreading
我一直在努力使这段代码工作,但我仍然看不出缺陷在哪里。
我正在尝试从新线程发出信号,因此主线程接收信号并执行函数。
如果我尝试在同一个线程中执行此操作,一切正常 - 但使用此代码,线程已创建,但信号从未连接。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore
class WorkThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
print("From thread")
self.emit(QtCore.SIGNAL("trying"))
return
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
def new_thread(self):
self.get_thread = WorkThread()
self.connect(self.get_thread, QtCore.SIGNAL("trying"), self.handle_trigger)
self.get_thread.start()
a = Foo()
a.new_thread()
我自己糊里糊涂地解决了这个问题,我认为这对你有用。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore
class WorkThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
tryThis = QtCore.Signal(str) #added this variable
def run(self):
print("From thread")
x = "trying"
self.tryThis.emit(QtCore.SIGNAL(x)) #pass your new variable like this
return
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
def new_thread(self):
self.get_thread = WorkThread()
self.get_thread.start()
self.get_thread.tryThis.connect(self.handle_trigger,QtCore.Qt.QueuedConnection) #passed it here
a = Foo()
a.new_thread()
根据评论进行了编辑。
您的代码存在一个主要问题。您实际上并没有启动 Qt 应用程序,因此没有主事件循环 运行。您必须添加以下行:
app = QApplication(sys.argv)
app.exec_()
此外,您应该使用 new-style Qt signals/slots if possible, or if you stick with the old-style, know that the Qt Signal should be in the form of a C function if you want it to also work with PySide。要将其更改为与 PySide 一起使用,它将是 QtCore.SIGNAL("trying()")
,而不是 QtCore.SIGNAL("trying")
。有关详细信息,请参阅评论(特别是我的评论和@ekhumoro 的评论)。
这是您的代码的工作版本(使用旧式 signals/slots),我尝试尽可能少地更改,以便您可以看到微小的更改。我不得不改用 PySide,但它也应该适用于 PyQt:
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import QtCore
import sys
class WorkThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
print("From thread")
self.emit(QtCore.SIGNAL("trying()"))
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
self.get_thread.quit()
self.get_thread.wait()
QApplication.quit()
def new_thread(self):
self.get_thread = WorkThread()
self.connect(self.get_thread, QtCore.SIGNAL("trying()"), self.handle_trigger)
self.get_thread.start()
a = Foo()
a.new_thread()
app = QApplication(sys.argv)
app.exec_()
这是一个使用新 signal/slot 样式的版本(请参阅@three_pineapples 评论)。这是在 PyQt/PySide.
中实现 signals/slots 的推荐方法
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import QtCore
import sys
class WorkThread(QtCore.QThread):
ranThread = QtCore.Signal()
# for PyQt, use QtCore.pyqtSignal() instead
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
print("From thread")
self.ranThread.emit()
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
self.get_thread.quit()
self.get_thread.wait()
QApplication.quit()
def new_thread(self):
self.get_thread = WorkThread()
self.get_thread.ranThread.connect(self.handle_trigger)
self.get_thread.start()
a = Foo()
a.new_thread()
app = QApplication(sys.argv)
app.exec_()
我一直在努力使这段代码工作,但我仍然看不出缺陷在哪里。 我正在尝试从新线程发出信号,因此主线程接收信号并执行函数。
如果我尝试在同一个线程中执行此操作,一切正常 - 但使用此代码,线程已创建,但信号从未连接。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore
class WorkThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
print("From thread")
self.emit(QtCore.SIGNAL("trying"))
return
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
def new_thread(self):
self.get_thread = WorkThread()
self.connect(self.get_thread, QtCore.SIGNAL("trying"), self.handle_trigger)
self.get_thread.start()
a = Foo()
a.new_thread()
我自己糊里糊涂地解决了这个问题,我认为这对你有用。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore
class WorkThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
tryThis = QtCore.Signal(str) #added this variable
def run(self):
print("From thread")
x = "trying"
self.tryThis.emit(QtCore.SIGNAL(x)) #pass your new variable like this
return
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
def new_thread(self):
self.get_thread = WorkThread()
self.get_thread.start()
self.get_thread.tryThis.connect(self.handle_trigger,QtCore.Qt.QueuedConnection) #passed it here
a = Foo()
a.new_thread()
根据评论进行了编辑。
您的代码存在一个主要问题。您实际上并没有启动 Qt 应用程序,因此没有主事件循环 运行。您必须添加以下行:
app = QApplication(sys.argv)
app.exec_()
此外,您应该使用 new-style Qt signals/slots if possible, or if you stick with the old-style, know that the Qt Signal should be in the form of a C function if you want it to also work with PySide。要将其更改为与 PySide 一起使用,它将是 QtCore.SIGNAL("trying()")
,而不是 QtCore.SIGNAL("trying")
。有关详细信息,请参阅评论(特别是我的评论和@ekhumoro 的评论)。
这是您的代码的工作版本(使用旧式 signals/slots),我尝试尽可能少地更改,以便您可以看到微小的更改。我不得不改用 PySide,但它也应该适用于 PyQt:
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import QtCore
import sys
class WorkThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
print("From thread")
self.emit(QtCore.SIGNAL("trying()"))
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
self.get_thread.quit()
self.get_thread.wait()
QApplication.quit()
def new_thread(self):
self.get_thread = WorkThread()
self.connect(self.get_thread, QtCore.SIGNAL("trying()"), self.handle_trigger)
self.get_thread.start()
a = Foo()
a.new_thread()
app = QApplication(sys.argv)
app.exec_()
这是一个使用新 signal/slot 样式的版本(请参阅@three_pineapples 评论)。这是在 PyQt/PySide.
中实现 signals/slots 的推荐方法from PySide.QtCore import *
from PySide.QtGui import *
from PySide import QtCore
import sys
class WorkThread(QtCore.QThread):
ranThread = QtCore.Signal()
# for PyQt, use QtCore.pyqtSignal() instead
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
print("From thread")
self.ranThread.emit()
class Foo(QObject):
def handle_trigger(self):
print ("trigger signal received")
self.get_thread.quit()
self.get_thread.wait()
QApplication.quit()
def new_thread(self):
self.get_thread = WorkThread()
self.get_thread.ranThread.connect(self.handle_trigger)
self.get_thread.start()
a = Foo()
a.new_thread()
app = QApplication(sys.argv)
app.exec_()