使用Python 2.5和PyQt 4.4.3,我无法在Python中找到任何此特定问题,所以对不起,如果我重复下面的其他Qt引用问题,但我不容易理解那C代码。PyQt线程和信号 - 如何正确检索值
我有两个班,一个GUI and a thread,我试图get return values从线程。我用the link in here作为编写my code的基础,它工作的很好。为了概括起来,在这里说明在代码中的问题(我不认为这个代码将在自身运行):
#!/usr/bin/python2.5
# this is a testing module, and almost everything in here is just there to make the script work
# the relevant issues for the testing are noted in comments
from PyQt4 import QtCore, QtGui
import sys, time
class MainWindow (QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.buttonDaemon = QtGui.QPushButton(self)
self.layout = QtGui.QVBoxLayout(self)
self.layout.addWidget(self.buttonDaemon)
self.setLayout(self.layout)
self.thread = Worker()
self.connect(self.thread, QtCore.SIGNAL('finished()'), self.unfreezeUi)
self.connect(self.thread, QtCore.SIGNAL('terminated()'), self.unfreezeUi)
#self.thread.stop.connect(self.stopped) # part of proposed solution
self.connect(self.thread, QtCore.SIGNAL('stopped(int)'), self.stopped) #adapted from proposed solution
self.connect(self.buttonDaemon, QtCore.SIGNAL('clicked()'), self.pressDaemon)
def unfreezeUi (self):
self.buttonDaemon.setEnabled(True)
# the problem begins below: I'm not using signals, or queue, or whatever, while I believe I should for StopSignal and DaemonRunning
def pressDaemon (self):
self.buttonDaemon.setEnabled(False)
if self.thread.isDaemonRunning():
self.thread.setDaemonStopSignal(True)
self.buttonDaemon.setText('Daemon - run code every %s sec'% 1)
else:
self.thread.startDaemon()
self.buttonDaemon.setText('Stop Daemon')
self.buttonDaemon.setEnabled(True)
# part of proposed solution
def stopped (self, val):
print 'stopped ' + str(val)
class Worker (QtCore.QThread):
daemonIsRunning = False
daemonStopSignal = False
daemonCurrentDelay = 0
def isDaemonRunning (self): return self.daemonIsRunning
def setDaemonStopSignal (self, bool): self.daemonStopSignal = bool
def __init__ (self, parent = None):
QtCore.QThread.__init__(self, parent)
self.exiting = False
self.thread_to_run = None
def __del__ (self):
self.exiting = True
self.thread_to_run = None
self.wait()
def run (self):
if self.thread_to_run != None:
self.thread_to_run(mode='continue')
#stop = QtCore.pyqtSignal(int) # part of proposed solution
def startDaemon (self, mode = 'run'):
if mode == 'run':
self.thread_to_run = self.startDaemon # I'd love to be able to just pass this as an argument on start() below
return self.start() # this will begin the thread
# this is where the thread actually begins
self.daemonIsRunning = True
print 'Daemon started'
self.daemonStopSignal = False
sleepStep = 0.1 # don't know how to interrupt while sleeping - so the less sleepStep, the faster StopSignal will work
# begins the daemon in an "infinite" loop
while self.daemonStopSignal == False and not self.exiting:
print 'Daemon running'
# here, do any kind of daemon service
delay = 0
while self.daemonStopSignal == False and not self.exiting and delay < 1:
print 'Daemon sleeping'
time.sleep(sleepStep) # delay is actually set by while, but this holds for 'sleepStep' seconds
delay += sleepStep
# daemon stopped, reseting everything
self.daemonIsRunning = False
print 'Daemon stopped'
#self.stop.emit(self.daemonIsRunning) # part of proposed solution
self.emit(QtCore.SIGNAL('stopped(int)'), self.daemonIsRunning) # adapted from proposed solution
self.emit(QtCore.SIGNAL('terminated'))
def main (args):
app = QtGui.QApplication(args)
win = MainWindow()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main(sys.argv)
芹苴这是相当大的,我希望这是很清楚的。主要观点在def pressDaemon
。特别是全部3 self.thread
调用。最后一个,self.thread.startDaemon()
就好了,就像例子一样。我怀疑这代表了任何问题。
问题是能够设置守护进程停止信号并检索值,如果它正在运行。我不确定是否可以在QtCore.QtThread
上设置停止信号,因为我尝试了相同的方法,但无效。但我很确定从emit
检索return
结果是不可能的。
所以,它就是这样。我正在使用直接调用线程类,并且我几乎肯定这不是一个好设计,并且在压力下运行时可能会失败。我阅读了关于该队列的内容,但我不确定这是否是正确的解决方案,或者我应该完全使用Qt,因为这是Python。只是也许我在做的事情没有任何问题。
编辑:建议的解决方案之后,我用它来使代码可以运行。再次感谢Max,为此!而且我也对这个建议留下了评论,让它清楚地说明它不利于解决问题。
我真的很感激你所有的时间来审查代码,甚至写在它的顶部! :)但我无法使用它。我实际上首先认为这是解决方案,直到能够尝试它! :(据我所知,你只是使用新的样式(http://tinyurl.com/ycdrypv)添加了一个信号,这对我不起作用。我需要**从MainWindow发送一个信号到Thread **,而不是我已经可以做的另一种方式,但我也不确定我应该试着发送这个信号,或者使用其他技术。再次,感谢您的时间,并且确保我会阅读所有的内容!:) – cregox 2010-05-18 16:31:28
哦,对不起。我误解了你。 你见过这个话题吗? http://stackoverflow.com/questions/638251/how-to-emit-cross-thread-signal-in-qt – 2010-05-19 07:07:56
好吧,以前没见过,但它对我的帮助仍然不大。它不仅仅是C,而且它只是在一个地方发送信号。它确实给了我一个新的'语法猜测'的想法...我会尝试它并让你知道。附:在SO/SE网站中,我只收到我的问题的答案,我的帖子的评论(答案或问题)以及我评论的帖子中的提及。在这种情况下,如果您通过提及我或者像我一样意外通知我,我只会阅读您的“答案”。 – cregox 2010-05-19 17:17:32