pythonにおけるスレッド内コンストラクタから登録する
Javaでいう Runnableのメソッドのような関数について、
以下のようなコードを教わりましたが、
def worker2(self):
print("Thread started")
try:
# Wait for 10 seconds or until the stop event is set
for i in range(10):
if self.stop_event.is_set():
print("Thread interrupted before completion")
return
# ミリ秒にできないか
time.sleep(1)
print("10 seconds passed")
#指定した時間が経過する間テキストボックスへの変更がないので
#入力値が確定するタイミングだろうか
# runOnUiThreadのような処理で Entry2に文字列の値を表示
except Exception as e:
print(f"Thread encountered an exception: {e}")
上記のコードのうちで、
time.sleep(1)だと1秒間の待機になりますが、
これをミリ秒単位で指定する方法を教えていただきたいのと、
このメソッド内での forループが終了したときに
androidでの
runOnUIのような感じで、UIスレッドで
ui要素の表示の変更
仮に
self.entry2
= ctk.CTkEntry( self, text="value is not set")
の表示内容を
"new value"
のような感じに変更したいのですが・・・
Pythonのスレッド内でミリ秒単位で待機するためには、
`time.sleep()`の代わりに`time.sleep()`の引数として
ミリ秒を秒に変換した値を渡す方法があります。
例えば、100ミリ秒の待機を実現したい場合は、
次のように記述します。
```python
time.sleep(0.1) # 100ミリ秒
```
次に、`worker2`メソッド内でUIスレッドに変更を加えたい場合、
Pythonの`tkinter`でUIを更新するには、
スレッドから直接UIを操作することができません。
`tkinter`では、UI更新はメインスレッドで行う必要があります。
`ctk`(CustomTkinter)を使用している場合も同様です。
スレッドからUIを更新するためには、
スレッド内でイベントをキューに追加し、
UIスレッドでそのイベントを処理する方法を取ります。
以下のように`after()`メソッドを使って、
UIスレッドで実行される関数を指定する方法があります。
```python
import time
import threading
import customtkinter as ctk
class App(ctk.CTk):
def __init__(self):
super().__init__()
self.entry2
= ctk.CTkEntry(self, text="value is not set")
self.entry2.pack(padx=20, pady=20)
self.stop_event = threading.Event()
def worker2(self):
print("Thread started")
try:
for i in range(10):
if self.stop_event.is_set():
print("Thread interrupted before completion")
return
# 100ミリ秒待機
time.sleep(0.1)
print("10 seconds passed")
# UIスレッドでUI要素の変更
self.after(0, self.update_entry)
except Exception as e:
print(f"Thread encountered an exception: {e}")
def update_entry(self):
self.entry2.configure(text="new value")
def start_thread(self):
thread = threading.Thread(target=self.worker2)
thread.start()
if __name__ == "__main__":
app = App()
app.start_thread()
app.mainloop()
```
このコードでは、
`worker2`メソッド内でスレッドが完了した後、
`after()`メソッドを使ってUIスレッドで`update_entry`メソッドを呼び出し、
`entry2`のテキストを更新しています。
`after()`はUIスレッドで実行されるコールバックをスケジュールするため、
UIの更新がスレッドと競合しないようにします。
ミリ秒単位の待機も含め、スレッド内での処理後にUIの更新が可能です。
コメント
コメントを投稿