webAPI関数はどのように呼び出してますか?self.this は何でしょう?
対象のウィジェットによっては期待通りの動作をすることも有るようですが
問題の原因は、
cursor の設定自体は設定値の変更に過ぎず、
実際に描写が変更されるのは、イベント処理で呼び出される関数の実行が終わり
処理がメインループに移った時になります。
tkinterのmainloop() のイベントループが、
マウスやボタンクリック時のイベント呼び出しや
描画の更新等を担っています。
これは単一のスレッドで順番に実行されている為、
イベント内で時間のかかる処理をすると、
一時的に他のイベントが処理されなくなり
ウィンドウが操作を受け付けなくなったり、固まった状態に陥ったりします。
一時的な回避策としては、明示的に描画の更新処理を呼び出す事です。
def webAPI(self):
self.this['cursor'] = 'watch'
self.update() # <-- これで明示的に描画更新できますが
# 時間のかかる処理 ... この間描画は更新されない。
# ウィンドウも操作を受け付けない状態になります
self.this['cursor'] = 'hand2'
時間のかかる処理は別スレッド等で行うようにすると、
ウィンドウの操作が固まる状態も解決できます。この場合であれば、
- 解決案1) webAPI()関数自体をスレッドで呼ぶように変更
- 解決案2) cursor変更の間の処理の身をスレッドで実行する
この場合、終了時のカーソル変更は別の場所で行うことになります。
他に、非同期IOを使うといった方法もありますが、
tkinter での事例が少ないのでお勧めはし辛いです。
一時的な回避策
python
1import time
2import tkinter as tk
3from tkinter import ttk
4
5root = tk.Tk()
6def onClick():
7 button['state'] = 'disable'
8 root['cursor'] = 'watch'
9 time.sleep(0.01) # <--- 少し待ってから。(これがないと複数回試したときに描画更新されないことあり)
10 root.update() # <--- 描画更新
11
12 time.sleep(5) # <--- 時間のかかる処理
13
14 button['state'] = 'normal'
15 root['cursor'] = 'hand1'
16button = ttk.Button(root, text="OK", command=onClick)
17button.pack()
18root.mainloop()
時間のかかる処理をスレッドで実行
python
1
2import time
3import tkinter as tk
4from tkinter import ttk
5from threading import Thread
6from contextlib import contextmanager
7
8DEFAULT_BUTTON_TEXT = "OK"
9
10@contextmanager
11def on_busy_task(root, button):
12 # 前準備と後始末
13 try:
14 button['state'] = 'disable'
15 button["text"] = "Running..."
16 root['cursor'] = 'watch'
17 yield
18 finally:
19 button['state'] = 'normal'
20 button["text"] = DEFAULT_BUTTON_TEXT
21 root['cursor'] = 'hand1'
22
23def heavyTask(root, button):
24 with on_busy_task(root, button):
25 time.sleep(5) # <-- 時間のかかる処理
26
27def onClick():
28 thread = Thread(target=heavyTask, args=(root, button), daemon=True)
29 thread.start()
30
31root = tk.Tk()
32button = ttk.Button(root, text=DEFAULT_BUTTON_TEXT, command=onClick)
33button.pack()
34root.mainloop()
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/12 23:52
2020/05/13 02:58