我使用pyside,但(我認爲)是一個通用的Qt問題。如何在使用QWaitCondition的QThread中使用QTimer? (pyside)
我知道QThread實現調用._exec()方法,所以我們應該在啓動的QThread上有一個事件循環。通過這種方式,我們可以在該線程上使用QTimer(我已經完成了這個工作,它完美地工作)。我的問題是,當QWaitCondition也被使用時,我想有一個「消費者」線程,等待從QWaitCondition通知(來自生產者)的無限循環。我遇到的問題是,使用這種設計,我無法在消費者線程中使用QTimer。
這是該方案的一個片段,我試圖解釋:
from PySide import QtGui
from PySide import QtCore
import sys
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.button = QtGui.QPushButton(self)
self.button.setText("Periodical")
self.button.clicked.connect(self.periodical_call)
self.thread = QtCore.QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.loop)
self.thread.start()
def closeEvent(self, x):
self.worker.stop()
self.thread.quit()
self.thread.wait()
def periodical_call(self):
self.worker.do_stuff("main window") # this works
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.do_stuff) # this also works
self.timer.start(2000)
def do_stuff(self):
self.worker.do_stuff("timer main window")
class Worker(QtCore.QObject):
def do_stuff_timer(self):
do_stuff("timer worker")
def do_stuff(self, origin):
self.origin = origin
self.wait.wakeOne()
def stop(self):
self._exit = True
self.wait.wakeAll()
def loop(self):
self.wait = QtCore.QWaitCondition()
self.mutex = QtCore.QMutex()
self._exit = False
while not self._exit:
self.wait.wait(self.mutex)
print "loop from %s" % (self.origin,)
self.timer = QtCore.QTimer()
self.timer.setSingleShot(True)
self.timer.timeout.connect(self.do_stuff_timer)
self.timer.start(1000) # <---- this doesn't work
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
frame = MainWindow()
frame.show()
sys.exit(app.exec_())
一旦你點擊我們得到這樣的輸出按鈕:
loop from main window
loop from timer main window
loop from timer main window
loop from timer main window
...
這意味着QTimer創建內部loop()方法永遠不會被事件循環執行。
如果我將設計從QWaitCondition更改爲信號(這是更好的設計方法),QTimer的工作原理,但我想知道爲什麼他們不工作時使用QWaitCondition。
他的QWaitCondition要求如何? – g19fanatic 2013-02-22 16:57:55