Pyqtアプリケーションでtime.sleepを使用できないのは、GUIスレッドがフリーズするため、この間GUIが完全にフリーズするためです。これを処理する方法を探していました。
QTimerを使おうとしましたが、別の関数にリンクする必要があるようです。 10秒待ってから、いくつかの関数を実行します。ただ待ってから現在の機能を続行する方法はありますか?
def num(self):
for i in range(1,999):
print i
#Add some sleep here
def testSleep(self):
QtCore.QTimer.singleShot(2000, self.num)
実際、私はスレッドの概念を使用せずにpyqtで使用するtime.sleepの代替手段を探していました。
そして私が理解した解決策は次のとおりです。
from PyQt4 import QtTest
QtTest.QTest.qWait(msecs)
これはtime.sleepと同様に機能し、GUIをレスポンシブにします。
ご回答ありがとうございます。
Num()の実行に数秒かかる場合にGUIをレスポンシブに保つ方法を質問していると思いますか? 2つのオプションがあります。
num()
が「作業」の多数の小さなチャンクで構成されている場合、チャンク間でapplication.processEvents()
を呼び出すことができます。これにより、GUIがイベントに応答できるようになります。対処するのが簡単な状況は、num()
時間のほとんどがループで費やされ、各反復の開始時または終了時にapplication.processEvents()
を呼び出す場合です。実際のアプリケーションでは、application
にアクセスできない場合は、PyQt4からqApp
をインポートします。より良いアプローチは、別のスレッドでnum()
を実行することです。 SO( this one のように)にはこれの多くの例があります)それを行う1つの方法は
QThread
をインスタンス化し、NumberCruncher
から派生し、num(self)
を定義し、戻る前にnum()
によって発行されるシグナル「done」を定義するクラス(たとえばQObject
)を定義します。numberCruncher.moveToThread(thread)
を呼び出すstarted
シグナルをnum
に接続しますおそらくもっとうまくいくかもしれませんが、いつでもsingleShot
を使用して関数を遅延で実行し、lambda
を使用して関数を引数で実行できます。
import sys
from PyQt4 import QtGui, QtCore
#def num(self, i):
def num(i):
print i
i += 1
if i < 999:
# run again after 2000ms with argument
QtCore.QTimer.singleShot(2000, lambda:num(i))
#QtCore.QTimer.singleShot(2000, lambda:self.num(i))
app = QtGui.QApplication(sys.argv)
# run first time with start argument
num(1)
#QtCore.QTimer.singleShot(2000, lambda:num(1))
sys.exit(app.exec_())
Pyqtメインイベントループでtime.sleep
を使用すると、GUIイベントループの応答が停止するため、使用できません。
QTimer
を使用すると、pyqtのソリューションは次のようになります。
import sys
from PyQt4 import QtGui, QtCore
application = QtGui.QApplication(sys.argv)
i=0
timer = QtCore.QTimer()
def num():
global i, timer
if i <999:
print ( i )
i += 1
else:
timer.stop()
timer.timeout.connect(num)
timer.start(2000)
sys.exit(application.exec_())