tkinterを使用して表示更新するプログラムを実行した場合、途中で更新が止まる現象が必ず発生していた。
ラベル表示(tkinter.Label())が重いからか、と思っていたが、その他の表示(tkinter.text()等)でも
発生したので、対応方法を色々試行してみたところ、以下の対応が妥当なようなことが分かったので記載。
<今回分かった違い>
<止まる場合>
tkinter.Label()を毎回丸ごと定義しなおして、表示更新。
<止まらない場合>
tkinter.Label()を1回使用したら、その後は必要なパラメータだけ.configで更新(※)。
<テスト用に作成したプログラムについて>
プログラム全般説明
5行の文字列と文字色の変更を200mS毎に繰り返す。
重い処理:tkinter.Labelは合計10ヶ作成。 (5種類×2面)
色と文字を変えるたびに、tkinter.Label()を定義しなおす。
軽い処理:tkinter.Labelは合計5ヶ作成。
色と文字を変える場合は、それぞれ、configでパラメータを書き換える。
99行目をコメントアウトすると、軽い処理を実行。
100行目をコメントアウトすると、重い処理を実行。
<実行画面>
<結果>
下記のプログラムを実行すると、
重い処理を実行した場合では、2000回程で、表示更新が止まる。
タスクマネージャーで見ていると、表示更新が止まる直前で、CPU使用率が50%程に上がる。(開始直後は3%)
但し、表示更新は止まっていても、afterメソッドによる繰り返しは継続している。
軽い処理を実行した場合は、4000回でも表示更新は継続。
注)
(※)labelの場合、.configによる変更でうまくいったが、set()で更新、get()で反映させるやり方でも
うまくいく場合もあったり、この辺はまだ勉強中。
- # -*- coding: utf-8 -*-
- import tkinter
- after_ID_Number = None
- root_window = tkinter.Tk()
- root_window.title("Test Window")
- root_window.geometry("250x200")
- def change_stop():
- global after_ID_Number
- if after_ID_Number != None:
- root_window.after_cancel(after_ID_Number)
- #############################################################################################
- # 重い処理 2000回程で、表示更新が止まる。
- #############################################################################################
- def text_change_heavy(i):
- global after_ID_Number
- if i == 0:
- entry_text00 = tkinter.Label(root_window, fg='blue', text='テキスト1-0', width=8)
- entry_text00.place(x=50, y=50)
- entry_text01 = tkinter.Label(root_window, fg='blue', text='テキスト1-1', width=8)
- entry_text01.place(x=50, y=70)
- entry_text02 = tkinter.Label(root_window, fg='blue', text='テキスト1-2', width=8)
- entry_text02.place(x=50, y=90)
- entry_text03 = tkinter.Label(root_window, fg='blue', text='テキスト1-3', width=8)
- entry_text03.place(x=50, y=110)
- entry_text04 = tkinter.Label(root_window, fg='blue', text='テキスト1-4', width=8)
- entry_text04.place(x=50, y=130)
- i = 1
- else:
- entry_text10 = tkinter.Label(root_window, fg='red', text='テキスト2-0', width=8)
- entry_text10.place(x=50, y=50)
- entry_text11 = tkinter.Label(root_window, fg='red', text='テキスト2-1', width=8)
- entry_text11.place(x=50, y=70)
- entry_text12 = tkinter.Label(root_window, fg='red', text='テキスト2-2', width=8)
- entry_text12.place(x=50, y=90)
- entry_text13 = tkinter.Label(root_window, fg='red', text='テキスト2-3', width=8)
- entry_text13.place(x=50, y=110)
- entry_text14 = tkinter.Label(root_window, fg='red', text='テキスト2-4', width=8)
- entry_text14.place(x=50, y=130)
- i = 0
- after_ID_Number = root_window.after(200, lambda:text_change_heavy(i,))
- print(after_ID_Number)
- #############################################################################################
- #############################################################################################
- # 軽い処理 4000回でも、表示更新は止まらない。
- #############################################################################################
- entry_text00 = tkinter.Label(root_window, fg='blue', text='テキスト1-0', width=8)
- entry_text00.place(x=50, y=50)
- entry_text01 = tkinter.Label(root_window, fg='blue', text='テキスト1-1', width=8)
- entry_text01.place(x=50, y=70)
- entry_text02 = tkinter.Label(root_window, fg='blue', text='テキスト1-2', width=8)
- entry_text02.place(x=50, y=90)
- entry_text03 = tkinter.Label(root_window, fg='blue', text='テキスト1-3', width=8)
- entry_text03.place(x=50, y=110)
- entry_text04 = tkinter.Label(root_window, fg='blue', text='テキスト1-4', width=8)
- entry_text04.place(x=50, y=130)
- def text_change_light(j):
- global after_ID_Number
- if j == 0:
- entry_text00.config(fg = 'blue')
- entry_text00.config(text = 'テキスト1-0')
- entry_text01.config(fg = 'blue')
- entry_text01.config(text = 'テキスト1-1')
- entry_text02.config(fg = 'blue')
- entry_text02.config(text = 'テキスト1-2')
- entry_text03.config(fg = 'blue')
- entry_text03.config(text = 'テキスト1-3')
- entry_text04.config(fg = 'blue')
- entry_text04.config(text = 'テキスト1-4')
- j = 1
- else:
- entry_text00.config(fg = 'red')
- entry_text00.config(text = 'テキスト2-0')
- entry_text01.config(fg = 'red')
- entry_text01.config(text = 'テキスト2-1')
- entry_text02.config(fg = 'red')
- entry_text02.config(text = 'テキスト2-2')
- entry_text03.config(fg = 'red')
- entry_text03.config(text = 'テキスト2-3')
- entry_text04.config(fg = 'red')
- entry_text04.config(text = 'テキスト2-4')
- j = 0
- after_ID_Number = root_window.after(200, lambda:text_change_light(j,))
- print(after_ID_Number)
- #############################################################################################
- #Run_button=tkinter.Button(root_window, width=5, text="Run", command = lambda:text_change_heavy(0,)) # 重い処理
- Run_button=tkinter.Button(root_window, width=5, text="Run", command = lambda:text_change_light(0,)) # 軽い処理
- Run_button.place(x=50, y=10)
- Stop_button=tkinter.Button(root_window, width=5, text="Stop", command = lambda:change_stop())
- Stop_button.place(x=150, y=10)
- root_window.mainloop()
コメント