web-dev-qa-db-ja.com

time.sleepと同等ですか?

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)
8
PAR

実際、私はスレッドの概念を使用せずにpyqtで使用するtime.sleepの代替手段を探していました。

そして私が理解した解決策は次のとおりです。

from PyQt4 import QtTest

QtTest.QTest.qWait(msecs)

これはtime.sleepと同様に機能し、GUIをレスポンシブにします。

ご回答ありがとうございます。

5
PAR

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に接続します
    • スレッドを開始します
2
Oliver

おそらくもっとうまくいくかもしれませんが、いつでも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_())
2
furas

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_())