QTimer.singleShot(..)
関数を使用して、ある程度の遅延を伴う特定のアクション/関数を実行することがよくあります。確かに、私はtime.sleep(..)
でもそれを行うことができますが、それは私のユーザーインターフェースをフリーズさせるでしょう。Python:QTimer.singleShot(..)関数の遅延展開を防ぐにはどうしたらいいですか?
パラメータを遅延関数に渡すことがあります。それはPythonのlambda
機能が役立つところです。次の例を見てください。
#######################################
# Print 'Hello world' vertically #
#######################################
myString = 'Hello world'
i = 0
for c in myString:
QtCore.QTimer.singleShot(10 + i*100, lambda: print(str(c)))
i += 1
出力は直感的には左のようになります。しかし、実際には、文字列 'd'の垂直リストを取得します。これは、指定された文字列の最後の文字(驚き)です。
_ _
H | d |
e | d |
l | d |
l | d |
o | Result you d | Result you
> would expect d > actually get!
w | d |
o | d |
r | d |
l | d |
d | d |
_| _|
QTimer.singleshot(..)
機能は「遅れ拡張」の原則を適用するように思えます。状況によっては素晴らしいですが、必ずしもそうではありません。
どのように拡張を制御できますか?すぐに展開することはできますか?
例コード:
新鮮なのpythonファイルに次のコードをコピー&ペースト、およびシェルから実行します。
import sys
from PyQt4 import QtGui, QtCore
class MainForm(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainForm, self).__init__(parent)
# create button
self.button = QtGui.QPushButton("QTimer.singleShot(..)", self)
self.button.clicked.connect(self.btnAction)
self.button.resize(200, 30)
def btnAction(self):
myString = 'Hello world'
i = 0
for c in myString:
QtCore.QTimer.singleShot(10 + i*100, lambda: print(str(c)))
i += 1
def main():
app = QtGui.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
main()
ボタンをクリックすると、あなたのシェルで「こんにちは世界の例が表示されます。
'lambda arg = c:print(str(arg))'。 – ekhumoro