PySide 将信号从 QThread 传递到另一个 QThread 中的插槽
PySide passing signals from QThread to a slot in another QThread
I solved my issue by moving the mySubQThread
run()
into the myQThread
run()
That said, I still would like to know why what I was attempting before didn't work.
我对线程处理还很陌生。我正在 运行 解决这个问题,我想我可能处理错了,不管怎样。我对不同的方法持开放态度,我知道这可能有点令人费解。
我有一个生成新派生的 GUI QThread
让我们在该线程中调用它 myQThread
,我正在 运行 通过创建另一个线程的进程调用它 mySubQThread
我遇到的问题如下,我在我的 GUI 中定义了信号,例如: signalA = QtCore.Signal(int)
和 myQThread
中的一个插槽 mySubQThread
中的插槽似乎从来没有收到信号.
这是一个工作示例。 (稍作修改)
from PySide import QtCore, QtGui
import time
class myQThread(QtCore.QThread):
myThreadSignal = QtCore.Signal(int)
def __init__(self, parent):
super(myQThread, self).__init__(parent=parent)
def run(self):
self.subThread = mySubQThread(parent=self)
self.myThreadSignal.connect(self.subThread.sub_thread_slot)
self.myThreadSignal.connect(self.test_slot)
print "starting subthread..."
self.subThread.start()
while self.subThread.isRunning():
print "myQThread is alive!"
time.sleep(1)
print "myQThread exiting run..."
@QtCore.Slot(int)
def my_thread_slot(self, a):
print "1b) Made it here!"
self.myThreadSignal.emit(a)
@QtCore.Slot(int)
def test_slot(self, a):
print "2a) Made it here!"
class mySubQThread(QtCore.QThread):
mySubSignalA = QtCore.Signal(int)
def __init__(self, parent):
super(mySubQThread, self).__init__(parent=parent)
self._abort = False
def run(self):
#Do some processing
#Wait for signal
self._abort = False
while not self._abort:
print "mySubQThread is alive!"
time.sleep(1)
print "mySubQThread exiting run..."
@QtCore.Slot(int)
def sub_thread_slot(self, a):
print "2b)Never make it here!"
self._abort = True
class myWidget(QtGui.QWidget):
myWidgetSignal = QtCore.Signal(int)
def __init__(self, parent=None):
super(myWidget, self).__init__(parent=parent)
#simple Widget to test this out....
myLayout = QtGui.QVBoxLayout()
self.runButton = QtGui.QPushButton("run")
self.runButton.clicked.connect(self.run_button_pressed)
self.otherButton = QtGui.QPushButton("other")
self.otherButton.clicked.connect(self.other_button_pressed)
myLayout.addWidget(self.runButton)
myLayout.addWidget(self.otherButton)
self.setLayout(myLayout)
@QtCore.Slot()
def run_button_pressed(self):
self.processThread = myQThread(self)
self.myWidgetSignal.connect(self.processThread.my_thread_slot)
self.myWidgetSignal.connect(self.test_slot)
self.processThread.start()
@QtCore.Slot()
def other_button_pressed(self):
self.myWidgetSignal.emit(1)
@QtCore.Slot(int)
def test_slot(self, a):
print "1a) Made it here!"
if __name__ == "__main__":
import sys
myApp = QtGui.QApplication(sys.argv)
myWin = myWidget()
myWin.show()
sys.exit(myApp.exec_())
这是一些示例输出:
请注意,如果您更改行:
self.subThread = mySubQThread(parent=self)
至
self.subThread = mySubQThread(parent=None)
它不再像示例输出中那样抱怨。两者都没有显示它到达 2B
QObject: Cannot create children for a parent that is in a different thread.
(Parent is myQThread(0x3c3faf0), parent's thread is QThread(0x2792548), current thread is myQThread(0x3c3faf0)
starting subthread...
myQThread is alive!mySubQThread is alive!
mySubQThread is alive!
myQThread is alive!
1b) Made it here!
2a) Made it here!
1a) Made it here!
问题是因为你覆盖了QThread.run()
。 run
方法默认包含处理信号处理的实现。
如果你想正确使用 signals/slots 你应该子类化 QObject
,把你的代码放在一个方法里,然后使用 moveToThread()
将 QObject
移动到您实例化的 QThread
的基础实例。然后,您可以 运行 您的代码,方法是将您的方法连接到 QThread.started
信号,然后调用 thread.start()
然后您可以以类似的方式重复创建子线程,方法是将该代码放入先前在线程中创建和启动的 QObject
的方法中。您在那里连接的信号和插槽将在线程和它的子线程之间正确生成。
是主线程和 QThread
之间正确通信的一个很好的例子,但您可以轻松地将它扩展到 QThreads
之间。只需修改 MyWorker.firstWork()
方法以启动新的 QThread
,就像 setupThread
方法中已经完成的那样。
I solved my issue by moving the
mySubQThread
run()
into themyQThread
run()
That said, I still would like to know why what I was attempting before didn't work.
我对线程处理还很陌生。我正在 运行 解决这个问题,我想我可能处理错了,不管怎样。我对不同的方法持开放态度,我知道这可能有点令人费解。
我有一个生成新派生的 GUI QThread
让我们在该线程中调用它 myQThread
,我正在 运行 通过创建另一个线程的进程调用它 mySubQThread
我遇到的问题如下,我在我的 GUI 中定义了信号,例如: signalA = QtCore.Signal(int)
和 myQThread
中的一个插槽 mySubQThread
中的插槽似乎从来没有收到信号.
这是一个工作示例。 (稍作修改)
from PySide import QtCore, QtGui
import time
class myQThread(QtCore.QThread):
myThreadSignal = QtCore.Signal(int)
def __init__(self, parent):
super(myQThread, self).__init__(parent=parent)
def run(self):
self.subThread = mySubQThread(parent=self)
self.myThreadSignal.connect(self.subThread.sub_thread_slot)
self.myThreadSignal.connect(self.test_slot)
print "starting subthread..."
self.subThread.start()
while self.subThread.isRunning():
print "myQThread is alive!"
time.sleep(1)
print "myQThread exiting run..."
@QtCore.Slot(int)
def my_thread_slot(self, a):
print "1b) Made it here!"
self.myThreadSignal.emit(a)
@QtCore.Slot(int)
def test_slot(self, a):
print "2a) Made it here!"
class mySubQThread(QtCore.QThread):
mySubSignalA = QtCore.Signal(int)
def __init__(self, parent):
super(mySubQThread, self).__init__(parent=parent)
self._abort = False
def run(self):
#Do some processing
#Wait for signal
self._abort = False
while not self._abort:
print "mySubQThread is alive!"
time.sleep(1)
print "mySubQThread exiting run..."
@QtCore.Slot(int)
def sub_thread_slot(self, a):
print "2b)Never make it here!"
self._abort = True
class myWidget(QtGui.QWidget):
myWidgetSignal = QtCore.Signal(int)
def __init__(self, parent=None):
super(myWidget, self).__init__(parent=parent)
#simple Widget to test this out....
myLayout = QtGui.QVBoxLayout()
self.runButton = QtGui.QPushButton("run")
self.runButton.clicked.connect(self.run_button_pressed)
self.otherButton = QtGui.QPushButton("other")
self.otherButton.clicked.connect(self.other_button_pressed)
myLayout.addWidget(self.runButton)
myLayout.addWidget(self.otherButton)
self.setLayout(myLayout)
@QtCore.Slot()
def run_button_pressed(self):
self.processThread = myQThread(self)
self.myWidgetSignal.connect(self.processThread.my_thread_slot)
self.myWidgetSignal.connect(self.test_slot)
self.processThread.start()
@QtCore.Slot()
def other_button_pressed(self):
self.myWidgetSignal.emit(1)
@QtCore.Slot(int)
def test_slot(self, a):
print "1a) Made it here!"
if __name__ == "__main__":
import sys
myApp = QtGui.QApplication(sys.argv)
myWin = myWidget()
myWin.show()
sys.exit(myApp.exec_())
这是一些示例输出:
请注意,如果您更改行:
self.subThread = mySubQThread(parent=self)
至
self.subThread = mySubQThread(parent=None)
它不再像示例输出中那样抱怨。两者都没有显示它到达 2B
QObject: Cannot create children for a parent that is in a different thread.
(Parent is myQThread(0x3c3faf0), parent's thread is QThread(0x2792548), current thread is myQThread(0x3c3faf0)
starting subthread...
myQThread is alive!mySubQThread is alive!
mySubQThread is alive!
myQThread is alive!
1b) Made it here!
2a) Made it here!
1a) Made it here!
问题是因为你覆盖了QThread.run()
。 run
方法默认包含处理信号处理的实现。
如果你想正确使用 signals/slots 你应该子类化 QObject
,把你的代码放在一个方法里,然后使用 moveToThread()
将 QObject
移动到您实例化的 QThread
的基础实例。然后,您可以 运行 您的代码,方法是将您的方法连接到 QThread.started
信号,然后调用 thread.start()
然后您可以以类似的方式重复创建子线程,方法是将该代码放入先前在线程中创建和启动的 QObject
的方法中。您在那里连接的信号和插槽将在线程和它的子线程之间正确生成。
QThread
之间正确通信的一个很好的例子,但您可以轻松地将它扩展到 QThreads
之间。只需修改 MyWorker.firstWork()
方法以启动新的 QThread
,就像 setupThread
方法中已经完成的那样。