非同期処理と GUI (P)

こちら にしたがって、TkEasyGUI を用いて GUI プログラムを書いている場合についてです。

定期的な処理

アニメーションなど、定期的に実行したい処理がある場合、window.read() に `timeout`` option をつければ大丈夫です。 これで、GUI イベントが来なくても、指定時間が来たらイベントとして認識してくれます。 後は、定期的に実行したい処理を、対応 event として記述するだけ。

while True:
    # 定期的に処理したいことがある場合は、timeout を指定するので十分
    event, values = self.window.read(timeout=1000, timeout_key='timeout')
    if event == sg.WIN_CLOSED:
        break
    print(f"event='{event}', code={ord(event[0])}, values={values}\n")
    if event == 'timeout':
        self.my_time.update(str(datetime.datetime.now()))

asyncio とGUI の協調

  • 作成プログラム

  • このプログラムは、webserver_test/test_server2.pyで起動される(偽)Web API にアクセスするプログラムとなっています。先に、test_server2.py を実行した状態で、simpleA_coroutine.py を実行させてください。

  • GUI のハンドラの中では、await は実行せず、web API 呼び出しも create_task して add_done_callbackを指定するだけにする。

    • これで、ハンドラの中で長時間停止することはない
    • 以下はclick のハンドラの例
    def listbox_click(self, value):  # 学生クリック時の動作
        if len(value) == 0:  # value はクリック要素が list として渡される
            return
        task0 = asyncio.create_task(self.score_service.get_scores(value[0]))
        task0.add_done_callback(callback_scores)
        print('Click performed.', value)
  • 一方で、定期的に co-routine にスケジュールの機会を与えないといけないので、Eventチェックの前に asyncio 処理を入れる
while True:
    await asyncio.sleep(0.01)  # 他の co-routines にスケジュール機会を与えるため
    # GUI Event は、timeout を設定。しないと、GUI event 来るまで「止まり」、
    # co-routine を見てくれなくなる
    event, values = self.window.read(timeout=200, timeout_key='timeout')
    if event == eg.WIN_CLOSED:
        break
    if event == 'timeout':
        continue
    print(f"event='{event}', code={ord(event[0])}, values={values}\n")
    if event == 'listbox':
        self.listbox_click(values['listbox'])

練習問題

課題作成に向けて、色々考えてみましょう。

  1. まえページのプログラムを改良して、PUT/POST を使えるようにすることはできそうですよね?
  • 当然、Firebase のproject も皆さんが作ったものを利用するようにしてくれないと、困りますが。
  1. 今回のscores_coroutine.py を真似れば、カレンダーっぽいものも作れそうな気がしませんか?例えば、こんな感じ。
  • 上には、共有カレンダー一覧を表示
  • 下には、選んだカレンダーの一覧を表示
  • あるいは、event 入力フォームも追加して、アカウントに登録。
  1. お絵かきツールの絵の内容(整数4つ組のリスト)を、クラウドに保存したり、クラウドから持ってきたりする拡張を加えてみる。

別に、なんか手が届きそうな気がしませんが? 課題的には、1. だけでも一応合格扱いになるし、2, 3, みたいな拡張入れれば、色々派手目なアプリになる気がしませんか?