Python tkinterの表示更新

Hardware & Software
Pocket

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()で反映させるやり方でも
 うまくいく場合もあったり、この辺はまだ勉強中。
  1. # -*- coding: utf-8 -*-
  2. import tkinter
  3. after_ID_Number = None
  4. root_window = tkinter.Tk()
  5. root_window.title("Test Window")
  6. root_window.geometry("250x200")
  7. def change_stop():
  8.   global after_ID_Number
  9.   if after_ID_Number != None:
  10.     root_window.after_cancel(after_ID_Number)
  11. #############################################################################################
  12. # 重い処理 2000回程で、表示更新が止まる。
  13. #############################################################################################
  14. def text_change_heavy(i):
  15.   global after_ID_Number
  16.   if i == 0:
  17.     entry_text00 = tkinter.Label(root_window, fg='blue', text='テキスト1-0', width=8)
  18.     entry_text00.place(x=50, y=50)
  19.     entry_text01 = tkinter.Label(root_window, fg='blue', text='テキスト1-1', width=8)
  20.     entry_text01.place(x=50, y=70)
  21.     entry_text02 = tkinter.Label(root_window, fg='blue', text='テキスト1-2', width=8)
  22.     entry_text02.place(x=50, y=90)
  23.     entry_text03 = tkinter.Label(root_window, fg='blue', text='テキスト1-3', width=8)
  24.     entry_text03.place(x=50, y=110)
  25.     entry_text04 = tkinter.Label(root_window, fg='blue', text='テキスト1-4', width=8)
  26.     entry_text04.place(x=50, y=130)
  27.     i = 1
  28.   else:
  29.     entry_text10 = tkinter.Label(root_window, fg='red', text='テキスト2-0', width=8)
  30.     entry_text10.place(x=50, y=50)
  31.     entry_text11 = tkinter.Label(root_window, fg='red', text='テキスト2-1', width=8)
  32.     entry_text11.place(x=50, y=70)
  33.     entry_text12 = tkinter.Label(root_window, fg='red', text='テキスト2-2', width=8)
  34.     entry_text12.place(x=50, y=90)
  35.     entry_text13 = tkinter.Label(root_window, fg='red', text='テキスト2-3', width=8)
  36.     entry_text13.place(x=50, y=110)
  37.     entry_text14 = tkinter.Label(root_window, fg='red', text='テキスト2-4', width=8)
  38.     entry_text14.place(x=50, y=130)
  39.     i = 0
  40.   after_ID_Number = root_window.after(200, lambda:text_change_heavy(i,))
  41.   print(after_ID_Number)
  42. #############################################################################################
  43. #############################################################################################
  44. # 軽い処理 4000回でも、表示更新は止まらない。
  45. #############################################################################################
  46. entry_text00 = tkinter.Label(root_window, fg='blue', text='テキスト1-0', width=8)
  47. entry_text00.place(x=50, y=50)
  48. entry_text01 = tkinter.Label(root_window, fg='blue', text='テキスト1-1', width=8)
  49. entry_text01.place(x=50, y=70)
  50. entry_text02 = tkinter.Label(root_window, fg='blue', text='テキスト1-2', width=8)
  51. entry_text02.place(x=50, y=90)
  52. entry_text03 = tkinter.Label(root_window, fg='blue', text='テキスト1-3', width=8)
  53. entry_text03.place(x=50, y=110)
  54. entry_text04 = tkinter.Label(root_window, fg='blue', text='テキスト1-4', width=8)
  55. entry_text04.place(x=50, y=130)
  56. def text_change_light(j):
  57.   global after_ID_Number
  58.   if j == 0:
  59.     entry_text00.config(fg = 'blue')
  60.     entry_text00.config(text = 'テキスト1-0')
  61.     entry_text01.config(fg = 'blue')
  62.     entry_text01.config(text = 'テキスト1-1')
  63.     entry_text02.config(fg = 'blue')
  64.     entry_text02.config(text = 'テキスト1-2')
  65.     entry_text03.config(fg = 'blue')
  66.     entry_text03.config(text = 'テキスト1-3')
  67.     entry_text04.config(fg = 'blue')
  68.     entry_text04.config(text = 'テキスト1-4')
  69.     j = 1
  70.   else:
  71.     entry_text00.config(fg = 'red')
  72.     entry_text00.config(text = 'テキスト2-0')
  73.     entry_text01.config(fg = 'red')
  74.     entry_text01.config(text = 'テキスト2-1')
  75.     entry_text02.config(fg = 'red')
  76.     entry_text02.config(text = 'テキスト2-2')
  77.     entry_text03.config(fg = 'red')
  78.     entry_text03.config(text = 'テキスト2-3')
  79.     entry_text04.config(fg = 'red')
  80.     entry_text04.config(text = 'テキスト2-4')
  81.     j = 0
  82.   after_ID_Number = root_window.after(200, lambda:text_change_light(j,))
  83.   print(after_ID_Number)
  84. #############################################################################################
  85. #Run_button=tkinter.Button(root_window, width=5, text="Run", command = lambda:text_change_heavy(0,))      # 重い処理
  86. Run_button=tkinter.Button(root_window, width=5, text="Run", command = lambda:text_change_light(0,))        # 軽い処理
  87. Run_button.place(x=50, y=10)
  88. Stop_button=tkinter.Button(root_window, width=5, text="Stop", command = lambda:change_stop())  
  89. Stop_button.place(x=150, y=10)
  90. root_window.mainloop()  
Hardware & SoftwarepythonSoftware
スポンサーリンク
シェアする
MTNブログ

コメント