2

我正在使用 PyQt4,并且创建了一个带有切换按钮的窗口。当我选择按钮时,我想启动一个尽快更新屏幕的循环。目前,它锁定了我的窗口,我无法再次选择按钮来关闭循环甚至移动窗口。我希望找到一种没有线程的方法。我不能发布我的实际代码,但这基本上就是我现在所拥有的。

self.connect(self.pushButton,SIGNAL("toggled(bool)"),self.testLoop)

def testLoop(self, bool):
    while bool:
        print "looping"
4

2 回答 2

4

您采用的方法主要取决于您的循环正在执行的任务的性质。

如果您可以将任务分解为非常小的步骤,则可以简单地使用计时器启动循环,然后调用processEvents每个步骤来更新您的 gui:

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.label = QtGui.QLabel('Count = 0', self)
        self.button = QtGui.QPushButton('Start', self)
        self.button.clicked.connect(self.handleButton)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.label)
        layout.addWidget(self.button)
        self._active = False

    def handleButton(self):
        if not self._active:
            self._active = True
            self.button.setText('Stop')
            QtCore.QTimer.singleShot(0, self.runLoop)
        else:
            self._active = False

    def closeEvent(self, event):
        self._active = False

    def runLoop(self):
        from time import sleep
        for index in range(100):
            sleep(0.05)
            self.label.setText('Count = %d' % index)
            QtGui.qApp.processEvents()
            if not self._active:
                break
        self.button.setText('Start')
        self._active = False

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
于 2012-08-30T19:33:28.207 回答
2

使用单独的线程进行循环。

import threading

self.connect(self.pushButton,SIGNAL("toggled(bool)"),self.on_testLoop)

def on_testLoop(self, bool):
    threading.Thread(target=self.testLoop, args=(bool,)).start()

def testLoop(self, bool):
    while bool:
        print "looping"

我发现另一种非常有用的方法是将函数变成生成器。这使您能够在每次迭代后做一些事情。

self.connect(self.pushButton,SIGNAL("toggled(bool)"),self.on_testLoop)

def on_testLoop(self, bool):
    for _ in testLoop(bool):
        # do some stuff, update UI elements etc.

def testLoop(self, bool):
    while bool:
        print "looping"
        yield

我不知道为此使用生成器有多好,因为我对 PyQt 和 gui 编程很陌生,但这对我来说效果很好。

于 2012-08-30T15:35:14.830 回答