PySide 信号未从 QThread 对象发送到插槽
PySide Signals not being sent to Slot, from QThread object
我正在使用一个多线程应用程序,其中创建了一个工作线程,它发出一个信号。
创建线程后,我将信号与对象插槽连接,它将执行一些操作。
问题是对象槽没有被调用,有人可以帮忙找出这段代码有什么问题吗?
import time
from PySide import QtCore
from PySide.QtCore import Slot, Signal
class Worker1(QtCore.QThread):
task_done_signal = Signal(int)
def __init__(self):
super(Worker1, self).__init__()
self._run = False
def run(self):
self._loop()
def _loop(self):
count = 0
while self._run:
print("running")
count += 1
self.task_done_signal.emit(count)
def start(self):
self._run = True
super(Worker1, self).start()
def stop(self):
self._run = False
class Worker1Listener(QtCore.QObject):
def __init__(self):
super(Worker1Listener, self).__init__()
@Slot()
def print_task(self, val):
print("listener: {}".format(val))
def test_signals_and_threads():
# create the thread
worker = Worker1()
# create the listener
listener = Worker1Listener()
# connect the thread signal with the slot
worker.task_done_signal.connect(listener.print_task)
worker.start()
time.sleep(5)
worker.stop()
time.sleep(5)
if __name__ == '__main__':
test_signals_and_threads()
您的代码有几个错误:
您必须有一个事件循环,以便 Qt 处理应用程序的各个对象之间的通信,在您的情况下,您必须使用 QCoreApplication
.
装饰器Slot
必须将函数参数的数据类型作为参数,在您的情况下:Slot(int)
你不应该使用 time.sleep 因为它是阻塞的并且不会让事件循环完成它的工作,一个可能的解决方案是在 [= 旁边使用 QEventLoop
15=].
总是建议给一个较短的时间来进行通信,为此我们使用QThread.msleep
。
当您在不同线程中的信号之间进行连接时,正确的选择是使用 Qt.QueuedConnection
选项。
import sys
from PySide import QtCore
class Worker1(QtCore.QThread):
task_done_signal = QtCore.Signal(int)
def __init__(self):
super(Worker1, self).__init__()
self._run = False
def run(self):
self._loop()
def _loop(self):
count = 0
while self._run:
print("running")
count += 1
self.task_done_signal.emit(count)
QtCore.QThread.msleep(1)
def start(self):
self._run = True
super(Worker1, self).start()
def stop(self):
self._run = False
class Worker1Listener(QtCore.QObject):
@QtCore.Slot(int)
def print_task(self, val):
print("listener: {}".format(val))
def test_signals_and_threads():
app = QtCore.QCoreApplication(sys.argv)
# create the thread
worker = Worker1()
# create the listener
listener = Worker1Listener()
# connect the thread signal with the slot
worker.task_done_signal.connect(listener.print_task, QtCore.Qt.QueuedConnection)
worker.start()
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(5000, loop.quit)
loop.exec_()
worker.stop()
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(5000, loop.quit)
loop.exec_()
#sys.exit(app.exec_())
if __name__ == '__main__':
test_signals_and_threads()
我正在使用一个多线程应用程序,其中创建了一个工作线程,它发出一个信号。 创建线程后,我将信号与对象插槽连接,它将执行一些操作。
问题是对象槽没有被调用,有人可以帮忙找出这段代码有什么问题吗?
import time
from PySide import QtCore
from PySide.QtCore import Slot, Signal
class Worker1(QtCore.QThread):
task_done_signal = Signal(int)
def __init__(self):
super(Worker1, self).__init__()
self._run = False
def run(self):
self._loop()
def _loop(self):
count = 0
while self._run:
print("running")
count += 1
self.task_done_signal.emit(count)
def start(self):
self._run = True
super(Worker1, self).start()
def stop(self):
self._run = False
class Worker1Listener(QtCore.QObject):
def __init__(self):
super(Worker1Listener, self).__init__()
@Slot()
def print_task(self, val):
print("listener: {}".format(val))
def test_signals_and_threads():
# create the thread
worker = Worker1()
# create the listener
listener = Worker1Listener()
# connect the thread signal with the slot
worker.task_done_signal.connect(listener.print_task)
worker.start()
time.sleep(5)
worker.stop()
time.sleep(5)
if __name__ == '__main__':
test_signals_and_threads()
您的代码有几个错误:
您必须有一个事件循环,以便 Qt 处理应用程序的各个对象之间的通信,在您的情况下,您必须使用
QCoreApplication
.装饰器
Slot
必须将函数参数的数据类型作为参数,在您的情况下:Slot(int)
你不应该使用 time.sleep 因为它是阻塞的并且不会让事件循环完成它的工作,一个可能的解决方案是在 [= 旁边使用
QEventLoop
15=].总是建议给一个较短的时间来进行通信,为此我们使用
QThread.msleep
。当您在不同线程中的信号之间进行连接时,正确的选择是使用
Qt.QueuedConnection
选项。
import sys
from PySide import QtCore
class Worker1(QtCore.QThread):
task_done_signal = QtCore.Signal(int)
def __init__(self):
super(Worker1, self).__init__()
self._run = False
def run(self):
self._loop()
def _loop(self):
count = 0
while self._run:
print("running")
count += 1
self.task_done_signal.emit(count)
QtCore.QThread.msleep(1)
def start(self):
self._run = True
super(Worker1, self).start()
def stop(self):
self._run = False
class Worker1Listener(QtCore.QObject):
@QtCore.Slot(int)
def print_task(self, val):
print("listener: {}".format(val))
def test_signals_and_threads():
app = QtCore.QCoreApplication(sys.argv)
# create the thread
worker = Worker1()
# create the listener
listener = Worker1Listener()
# connect the thread signal with the slot
worker.task_done_signal.connect(listener.print_task, QtCore.Qt.QueuedConnection)
worker.start()
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(5000, loop.quit)
loop.exec_()
worker.stop()
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(5000, loop.quit)
loop.exec_()
#sys.exit(app.exec_())
if __name__ == '__main__':
test_signals_and_threads()