PyQt:qthread通过信号中断
我是pyqt的新手,所以我希望我所做的不会有什么奇怪的事情。我试图通过使用PyQt信号在QT线程之间创建交互。特别是,我想做的是从线程发出一个信号,这个信号应该会中断线程运行特定方法所做的事情。顺便说一下,我在做这件事时遇到了一些问题,所以我想知道我所做的是否合法 例如,现在我正试图做这样的事情:PyQt:qthread通过信号中断,qt,pyqt,signals,pyqt4,qthread,Qt,Pyqt,Signals,Pyqt4,Qthread,我是pyqt的新手,所以我希望我所做的不会有什么奇怪的事情。我试图通过使用PyQt信号在QT线程之间创建交互。特别是,我想做的是从线程发出一个信号,这个信号应该会中断线程运行特定方法所做的事情。顺便说一下,我在做这件事时遇到了一些问题,所以我想知道我所做的是否合法 例如,现在我正试图做这样的事情: import sys import time from PyQt4 import QtGui as qt from PyQt4 import QtCore as qtcore from PyQt4.Q
import sys
import time
from PyQt4 import QtGui as qt
from PyQt4 import QtCore as qtcore
from PyQt4.QtCore import QThread
import threading
app = qt.QApplication(sys.argv)
class widget(qt.QWidget):
def __init__(self, parent=None):
qtcore.QObject.__init__(self)
def appinit(self):
self.mysignal = qtcore.SIGNAL("mysignal")
thread = mythread(self)
thread.start()
time.sleep(5)
print "before emit",str(threading.current_thread())
self.emit(self.mysignal,"hello, I'm thread "+str(threading.current_thread()))
print "after emit",str(threading.current_thread())
class mythread(QThread):
def __init__(self,parent):
qtcore.QThread.__init__(self, parent=app)
self.parent=parent
def run(self):
self.mysignal = qtcore.SIGNAL("mysignal")
self.connect(self.parent, self.mysignal, self.myfunc)
for i in range(15):
print "**",threading.current_thread(),i
time.sleep(1)
def myfunc(self, msg):
print threading.current_thread(), msg, "Enter"
time.sleep(5)
print threading.current_thread(), msg, "Exit"
def main():
mywidget = widget()
mywidget.show()
qtcore.QTimer.singleShot(0, mywidget.appinit)
sys.exit(app.exec_())
main()
我得到的结果是:
** <_DummyThread(Dummy-1, started daemon 1968)> 0
** <_DummyThread(Dummy-1, started daemon 1968)> 1
** <_DummyThread(Dummy-1, started daemon 1968)> 2
** <_DummyThread(Dummy-1, started daemon 1968)> 3
** <_DummyThread(Dummy-1, started daemon 1968)> 4
before emit <_MainThread(MainThread, started 2928)>
<_MainThread(MainThread, started 2928)> hello, I'm thread <_MainThread(MainThread, started 2928)> Enter
** <_DummyThread(Dummy-1, started daemon 1968)> 5
** <_DummyThread(Dummy-1, started daemon 1968)> 6
** <_DummyThread(Dummy-1, started daemon 1968)> 7
** <_DummyThread(Dummy-1, started daemon 1968)> 8
** <_DummyThread(Dummy-1, started daemon 1968)> 9
<_MainThread(MainThread, started 2928)> hello, I'm thread <_MainThread(MainThread, started 2928)> Exit
after emit <_MainThread(MainThread, started 2928)>
** <_DummyThread(Dummy-1, started daemon 1968)> 10
** <_DummyThread(Dummy-1, started daemon 1968)> 11
** <_DummyThread(Dummy-1, started daemon 1968)> 12
** <_DummyThread(Dummy-1, started daemon 1968)> 13
** <_DummyThread(Dummy-1, started daemon 1968)> 14
**0
** 1
** 2
** 3
** 4
发射前
您好,我是thread Enter
** 5
** 6
** 7
** 8
** 9
你好,我是线程出口
后发
** 10
** 11
** 12
** 13
** 14
我本来希望mythread中断它的执行并运行myfunc。顺便说一句,mythread不会中断它的执行,函数myfunc实际上是由主线程运行的。我试着做相反的事情(生成的线程向主线程发送一个信号),结果它成功了
我想我还没有完全理解信号是如何工作的,以及是否有可能做我想做的事情。有什么线索吗?我在网上寻找解决方案,但没有结果
谢谢好的,据我所知,您希望线程在进一步迭代之前进入5秒睡眠
import sys
import time
from PyQt4 import QtGui as qt
from PyQt4 import QtCore as qtcore
from PyQt4.QtCore import QThread
import threading
app = qt.QApplication(sys.argv)
class widget(qt.QWidget):
def __init__(self, parent=None):
qtcore.QObject.__init__(self)
def appinit(self):
self.mysignal = qtcore.SIGNAL("mysignal")
thread = mythread(self,self.mysignal)
thread.start()
time.sleep(5)
print "before emit",str(threading.current_thread())
self.emit(self.mysignal,"hello, I'm thread "+str(threading.current_thread()))
print "after emit",str(threading.current_thread())
class mythread(QThread):
def __init__(self,parent,sig):
qtcore.QThread.__init__(self, parent=app)
self.parent=parent
self.mysignal = sig
self.stop_event=threading.Event()
self.connect(self.parent, self.mysignal, self.setIt)
def run(self):
for i in range(15):
if self.stop_event.isSet():
self.myfunc()
print "**",threading.current_thread(),i
time.sleep(1)
def setIt(self,msg):
self.stop_event.set()
self.msg = msg
def myfunc(self):
print threading.current_thread(),self.msg , "Enter"
time.sleep(5)
print threading.current_thread(),self.msg , "Exit"
self.stop_event.clear()
def main():
mywidget = widget()
mywidget.show()
qtcore.QTimer.singleShot(0, mywidget.appinit)
sys.exit(app.exec_())
main()
输出:
** <_DummyThread(Dummy-1, started daemon 7312)> 0
** <_DummyThread(Dummy-1, started daemon 7312)> 1
** <_DummyThread(Dummy-1, started daemon 7312)> 2
** <_DummyThread(Dummy-1, started daemon 7312)> 3
** <_DummyThread(Dummy-1, started daemon 7312)> 4
before emit <_MainThread(MainThread, started 232)>
after emit <_MainThread(MainThread, started 232)>
<_DummyThread(Dummy-1, started daemon 7312)> hello, I'm thread <_MainThread(MainThread, started 232)> Enter
<_DummyThread(Dummy-1, started daemon 7312)> hello, I'm thread <_MainThread(MainThread, started 232)> Exit
** <_DummyThread(Dummy-1, started daemon 7312)> 5
** <_DummyThread(Dummy-1, started daemon 7312)> 6
** <_DummyThread(Dummy-1, started daemon 7312)> 7
** <_DummyThread(Dummy-1, started daemon 7312)> 8
** <_DummyThread(Dummy-1, started daemon 7312)> 9
** <_DummyThread(Dummy-1, started daemon 7312)> 10
** <_DummyThread(Dummy-1, started daemon 7312)> 11
** <_DummyThread(Dummy-1, started daemon 7312)> 12
** <_DummyThread(Dummy-1, started daemon 7312)> 13
** <_DummyThread(Dummy-1, started daemon 7312)> 14
**0
** 1
** 2
** 3
** 4
发射前
后发
您好,我是thread Enter
你好,我是线程出口
** 5
** 6
** 7
** 8
** 9
** 10
** 11
** 12
** 13
** 14
通过信号中断同步代码(如长时间运行的循环)不起作用:线程间的信号/插槽需要在接收线程中有一个事件循环(即,必须通过调用exec()在run()中输入);要调用插槽,接收线程必须返回到事件循环;也就是说,如果你有一个长时间运行的循环,事件循环将被阻塞,插槽将永远不会被调用。我想我现在开始更好地理解了。顺便说一句,我将mythread.run()中的for循环替换为app.exec\uz()。结果是,函数myfunc仍然由主线程调用,因此我觉得有其他问题。