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"

私が非常に便利だと思ったもう1つの方法は、関数をジェネレーターにすることでした。これにより、各反復の後に何かを行うことができます。

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 に答える