前提・実現したいこと
現在,python, tkinterを用いたGUIアプリケーションの作成をしています。そのアプリの中で,ボタン押し後にループ処理を開始し,そのループ内で動的にGUI上のラベルのテキストを変更をする機能を持たせたいと考えています。GUIの表示変更処理と,ループ処理をそれぞれ異なるスレッドで動かさなければいけないと考え,コードを書いている状況です。
発生している問題
そこで以下のコードのよう,GUI表示をスレッド化し,ボタン押しに伴うループ処理内でラベルのテキストを変更するよう処理を記述したつもりでした。しかしながら,ボタンを押したとしてもGUI上のテキストは動的に更新されず,ループ処理全体が終了したのちにやっとテキストが更新されてしまいます。ループ処理の実行はprint処理にて確認をしています。
ループ処理中の状態:ボタンが押された状態でテキストが更新されない
該当のソースコード
python
1import time 2import threading 3import tkinter as tk 4 5class GUI(threading.Thread): 6 7 def __init__(self): 8 threading.Thread.__init__(self) 9 self.value = 0 10 11 def start(self): 12 self.root = tk.Tk() 13 # ラベルの表示 14 self.label = tk.Label(self.root, text=self.value) 15 self.label.pack() 16 # ボタンの表示 17 self.button = tk.Button(self.root, text='push', command=self.change_value) 18 self.button.pack() 19 self.root.mainloop() 20 21 22 def change_value(self): 23 24 for value in range(100): 25 time.sleep(0.05) 26 self.value = value 27 # ラベルの値を変更 28 self.label['text'] = str(self.value) 29 # ラベルに表示されるだろう値を表示 30 print(self.value) 31 32if __name__ == '__main__': 33 gui = GUI() 34 gui.start()
試したこと
そこで,ラベルの値を変更する処理もさらに別のスレッドで処理する必要があるのかと考え,以下のようにコードを変更しました。しかしながら,コードの変更前と変わらず,ボタン押しをしても,GUI上のテキストは動的に更新されない状況です。
スレッド別に処理を実行することで,テキスト表示の変更をループ処理内で動的に変更可能と考えていたのですが,発想から根本的に間違っているのでしょうか?あるいはコードそのものが根本的に間違っているのでしょうか?恐れ入りますが,ご示唆いただけると幸いです。
python
1import time 2import threading 3import tkinter as tk 4 5class GUI(threading.Thread): 6 7 def __init__(self): 8 threading.Thread.__init__(self) 9 self.value = 0 10 11 def start(self): 12 self.root = tk.Tk() 13 # ラベルの表示 14 self.label = tk.Label(self.root, text=self.value) 15 self.label.pack() 16 # ボタンの表示 17 self.button = tk.Button(self.root, text='push', command=self.change_value) 18 self.button.pack() 19 self.root.mainloop() 20 21 22 def change_value(self): 23 24 for value in range(100): 25 time.sleep(0.05) 26 self.value = value 27 28 # 新たに変更した個所 29 new_thread = threading.Thread(target=self.change_label) 30 new_thread.start() 31 32 # ラベルに表示されるだろう値を表示 33 print(self.value) 34 35 def change_label(self): 36 self.label['text'] = str(self.value) 37 38if __name__ == '__main__': 39 gui = GUI() 40 gui.start()
補足
python = 3.7.6
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/20 22:40