【发布时间】:2014-03-10 00:08:37
【问题描述】:
我对 pyqt 很陌生,所以我希望我正在尝试做的事情不会有什么奇怪的。我试图通过使用 PyQt 信号在 QThreads 之间创建交互。特别是,我想做的是从线程发出信号,该信号应该中断线程正在执行的操作以运行特定方法。顺便说一句,我在这样做时遇到了一些问题,所以我想知道我正在尝试做的事情是否合法。
例如,现在我正在尝试做这样的事情:
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
我实际上希望 mythread 中断其执行并运行 myfunc。顺便说一句,mythread 并没有中断它的执行,而函数 myfunc 实际上是由主线程运行的。我试图做相反的事情(生成的线程向主线程发送一个信号)并且它可以工作。
我想我还没有完全理解信号是如何工作的,以及是否有可能做我想做的事。有什么线索吗?我在网上寻找解决方案,但没有结果。
谢谢
【问题讨论】:
-
通过信号中断同步代码(如长时间运行的循环)将不起作用:跨线程的信号/槽需要在接收线程中的事件循环(即必须在 run() 中输入,通过调用执行());要调用槽,接收线程必须返回事件循环; IE。如果你有一个长时间运行的循环,事件循环将被阻塞并且插槽永远不会被调用。
-
我想我现在开始理解得更好了。顺便说一句,我用 app.exec_() 替换了 mythread.run() 中的 for 循环。结果是myfunc函数还是被主线程调用了,所以感觉还有点不对劲。
标签: qt pyqt signals pyqt4 qthread