我通过将
来解决了我的问题mySubQThread
run()
移到myQThread
run()
那就是说,我仍然想知道为什么我以前尝试过的东西不起作用。
我对线程很新。我遇到了这个问题,我想我可能正在接近错误,无论如何这里都是。我对另一种方法持开放态度,我知道这可能有点令人费解。
我有一个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!
答案 0 :(得分:3)
问题是因为您已覆盖QThread.run()
。默认情况下,run
方法包含一个处理信号处理的实现。
如果要正确使用信号/插槽,则应将QObject
子类化,将代码放在其中的方法中,然后使用moveToThread()
将QObject
移动到基础实例您实例化的QThread
。然后,您可以将方法与QThread.started
信号相关联,然后调用thread.start()
然后,您可以通过将该代码放在先前在线程中创建并启动的QObject
的方法中,以类似的方式重复创建子线程。你在那里连接的信号和插槽将正确地在线程和它的子线程之间建立。
This是主线程与QThread
之间正确沟通的一个很好的示例,但您可以轻松地将其扩展到QThreads
之间。只需修改MyWorker.firstWork()
方法即可启动新的QThread
,就像setupThread
方法中已经完成的那样。