イーベントでTimerしてみる?
今回はQtのtimerEventのメモ。
QtのQObjectにはtimerEventメソッドがあり、これをオーバーライドする事で時間にそって何らかな作業を行う事ができます。
とりあえずサンプルコード
QtのQObjectにはtimerEventメソッドがあり、これをオーバーライドする事で時間にそって何らかな作業を行う事ができます。
とりあえずサンプルコード
# -*- coding:utf-8 -*- import datetime from PyQt4 import QtGui, QtCore class TimerWidget(QtGui.QWidget): def __init__(self, parent=None): super(TimerWidget, self).__init__(parent) # Tree Viewを作成。---------------------------------------------------- model = QtGui.QStandardItemModel(0, 0) self.view = QtGui.QTreeView() self.view.setModel(model) # --------------------------------------------------------------------- layout = QtGui.QVBoxLayout(self) layout.addWidget(self.view) self.timerId = self.startTimer(1000) # TimerEventをスタート def timerEvent(self, event): ''' オーバーライド用のtimerEventメソッド。 ここに処理を記述する。 ''' if event.timerId() == self.timerId: # 引数eventのタイマーIDが先に行ったself.timerIdと一致している場合 # アイテムを追加する。 model = self.view.model() item = QtGui.QStandardItem( datetime.datetime.now().strftime('%Y/%m/%d, %H:%M:%S') ) model.setItem(model.rowCount(), 0, item) if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) win = TimerWidget() win.show() sys.exit(app.exec_())で、こんな感じになります。

このサンプルの場合、1秒ごとにTreeViewに現在時刻を表示するアイテムを追加していきます。
20行目の
この時の戻り値をクラス内変数に入れておいて、timerEvent内でイベントの現在のtimerIdと比較して一致していたら任意の挙動を実行するように実装してやります。
簡単ですねヽ(=´▽`=)ノ
さて、アイテムが1秒ごとに定期的に追加されていてもUIは普通に操作する事が可能ですが、内部はメインスレッドでイベントを実行しているっぽいです。 例えば上のソースコードのうち、timerEventの部分を下記のように書き換えてみます。
今回はskeepで強制的に止めましたが、思い処理をここに書くと当然処理時間中はUIの操作が出来なくなってしまうので重すぎる操作は別スレッドにしてやりましょう。
スレッドに関してはこちらを参照。
また、2つのtimerを作成して片方に重い処理をさせるとどうなるを試しましたが、やはり処理が重いパートでは完全にストップしてしまい、もう一方のtimerEventは実行されません。
と、使う部分は若干選びますが、これを利用すると簡単なアニメーションなんかも実装する事が出来ます。
夢広がリング~~(∩´∀`)∩(´∀`)∩(´∀`∩)
20行目の
self.startTimer(1000)でタイマーイベントへのIDを生成しています。引数はイベント実行のサイクル(ミリ秒)で、今回の場合は1000なんで1秒ごとに実行します。
この時の戻り値をクラス内変数に入れておいて、timerEvent内でイベントの現在のtimerIdと比較して一致していたら任意の挙動を実行するように実装してやります。
簡単ですねヽ(=´▽`=)ノ
さて、アイテムが1秒ごとに定期的に追加されていてもUIは普通に操作する事が可能ですが、内部はメインスレッドでイベントを実行しているっぽいです。 例えば上のソースコードのうち、timerEventの部分を下記のように書き換えてみます。
if event.timerId() == self.timerId: import time time.sleep(3) model = self.view.model() item = QtGui.QStandardItem(str(time.time())) model.setItem(model.rowCount(), 0, item)するとtimeモジュールのsleepで3秒待っている間はUIを操作する事ができなくなります。その後また次のtimerEventに入ってしまうため、UIを操作出来るのはイベントとイベントの合間の一瞬だけになってしまいます。
今回はskeepで強制的に止めましたが、思い処理をここに書くと当然処理時間中はUIの操作が出来なくなってしまうので重すぎる操作は別スレッドにしてやりましょう。
スレッドに関してはこちらを参照。
また、2つのtimerを作成して片方に重い処理をさせるとどうなるを試しましたが、やはり処理が重いパートでは完全にストップしてしまい、もう一方のtimerEventは実行されません。
# -*- coding:utf-8 -*- import datetime from PyQt4 import QtGui, QtCore class TimerWidget(QtGui.QWidget): def __init__(self, parent=None): super(TimerWidget, self).__init__(parent) self.timerIdA = self.startTimer(1000) self.timerIdB = self.startTimer(200) def timerEvent(self, event): if event.timerId() == self.timerIdA: import time time.sleep(3) print('Done A') elif event.timerId() == self.timerIdB: print('Done B') if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) win = TimerWidget() win.show() sys.exit(app.exec_())まぁ、timerEvent内で処理を記述してるわけですから当たり前ですネ(;一_一)
と、使う部分は若干選びますが、これを利用すると簡単なアニメーションなんかも実装する事が出来ます。
夢広がリング~~(∩´∀`)∩(´∀`)∩(´∀`∩)
スポンサーサイト