fc2ブログ

    イーベントでTimerしてみる?

     今回はQtの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_())
    
    で、こんな感じになります。
    timerEvent001.jpg


     このサンプルの場合、1秒ごとにTreeViewに現在時刻を表示するアイテムを追加していきます。
     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内で処理を記述してるわけですから当たり前ですネ(;一_一)



     と、使う部分は若干選びますが、これを利用すると簡単なアニメーションなんかも実装する事が出来ます。
     夢広がリング~~(∩´∀`)∩(´∀`)∩(´∀`∩)
    スポンサーサイト



    コメントの投稿

    非公開コメント

    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココのメールアドレスからご連絡できますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR