実現したいこと
tkinterのafter_cancel()を使た後再びafter()を使って疑似的に二重ループを回したい。
1号室の1番目の窓を選択
↓
1号室の2番目の窓を選択
↓
1号室の3番目の窓を選択
↓
1号室の4番目の窓を選択
↓
2号室の1番目の窓を選択
↓
2号室の2番目の窓を選択
↓
2号室の3番目の窓を選択
↓
2号室の4番目の窓を選択
↓
というふうに、何秒かおきに自動で処理を進めたいのですが、
tkinterでは構造上、二重のforループを使えないみたいで、
疑似的にafter関数を使って実現することにしました。
・・・
該当のソースコード
Python
1import customtkinter 2import datetime 3import time 4 5class MyButtonFrame(customtkinter.CTkFrame): 6 def __init__(self, master, values): 7 super().__init__(master) 8 self.values = values 9 self.buttons = [] 10 11 for i, value in enumerate(self.values): 12 button = customtkinter.CTkButton(self, text=value) 13 if i<5: 14 button.grid(row=0, column=i, padx=10, pady=(10, 0), sticky="nw") 15 else:#改行して表示 16 button.grid(row=1, column=i-5, padx=10, pady=(10, 10), sticky="nw") 17 self.buttons.append(button) 18 19class Disproom(customtkinter.CTk): 20 def __init__(self): 21 super().__init__() 22 23 self.title("各部屋制御画面") 24 self.geometry("600x300") 25 26 #フレームの作成(ダミーデータで埋める) 27 #本格的な描画は末尾の関数で実行 28 #------------------------------------------------------------ 29 #時計フレーム 30 self.clock_frame = customtkinter.CTkFrame(self) 31 self.clock_frame.grid(row=0, column=0, padx=10, pady=(10, 0), sticky="nw") 32 #時計フレーム内のラベル 33 self.lblClock_ymd = customtkinter.CTkLabel(self.clock_frame, text="99/99/99") 34 self.lblClock_ymd.grid(row=0, column=0, padx=10, pady=(0, 0), sticky="nw") 35 self.lblClock_hms = customtkinter.CTkLabel(self.clock_frame, text="99:99:99") 36 self.lblClock_hms.grid(row=1, column=0, padx=10, pady=(0, 0), sticky="nw") 37 self.lblClock_free = customtkinter.CTkLabel(self.clock_frame, text="") 38 self.lblClock_free.grid(row=2, column=0, padx=10, pady=(0, 0), sticky="nw") 39 #---------------------------------------------------------- 40 41 #各窓制御フレーム 42 self.window_control_frame = customtkinter.CTkFrame(self) 43 self.window_control_frame.grid(row=0, column=3, padx=10, pady=(10, 0), sticky="new") 44 #各窓制御フレームの題名 45 self.lblwindow_control_caption = customtkinter.CTkLabel(self.window_control_frame, text="天窓制御 ON No.0 制御中 (目標角 99.9°) ") 46 self.lblwindow_control_caption.grid(row=0, column=0, padx=10, pady=(0, 0), sticky="nw",columnspan=2) 47 #東天窓フレーム 48 self.window_frame_east = customtkinter.CTkFrame(self.window_control_frame) 49 self.window_frame_east.grid(row=2, column=0, padx=10, pady=(10, 0), sticky="new") 50 self.lblwindow_east_1 = customtkinter.CTkLabel(self.window_frame_east, text="東天窓") 51 self.lblwindow_east_1.grid(row=0, column=0, padx=10, pady=(0, 0), sticky="nw") 52 self.lblwindow_east_2 = customtkinter.CTkLabel(self.window_frame_east, text="No.1") 53 self.lblwindow_east_2.grid(row=0, column=1, padx=10, pady=(0, 0), sticky="nw") 54 self.lblwindow_east_3 = customtkinter.CTkLabel(self.window_frame_east, text="温度") 55 self.lblwindow_east_3.grid(row=0, column=2, padx=10, pady=(0, 0), sticky="nw") 56 self.lblwindow_east_4 = customtkinter.CTkLabel(self.window_frame_east, text="角度") 57 self.lblwindow_east_4.grid(row=1, column=2, padx=10, pady=(0, 0), sticky="nw") 58 self.lblwindow_east_temp = customtkinter.CTkLabel(self.window_frame_east, text="99.9") 59 self.lblwindow_east_temp.grid(row=0, column=3, padx=10, pady=(0, 0), sticky="nw") 60 self.lblwindow_east_angle = customtkinter.CTkLabel(self.window_frame_east, text="99.9") 61 self.lblwindow_east_angle.grid(row=1, column=3, padx=10, pady=(0, 0), sticky="nw") 62 #省略 63 #--------------------------------------------------------- 64 65 #-------------------------------------------------------- 66 #時計を起動 67 self.updateClocklbl() 68 #各部屋制御ルーチン 69 self.Selectroom() 70 71 def updateClocklbl(self): 72 #再帰呼び出し 73 self.lblClock_hms.after(1000, self.updateClocklbl)#1000[ms] 74 75 now = datetime.datetime.now() 76 ymd = now.strftime("%y/%m/%d") 77 hms = now.strftime("%H:%M:%S") 78 #値を更新して再配置 79 self.lblClock_ymd = customtkinter.CTkLabel(self.clock_frame, text=ymd) 80 self.lblClock_ymd.grid(row=0, column=0, padx=10, pady=(0, 0), sticky="nw") 81 self.lblClock_hms = customtkinter.CTkLabel(self.clock_frame, text=hms) 82 self.lblClock_hms.grid(row=1, column=0, padx=10, pady=(0, 0), sticky="nw") 83 84 85 def Selectroom(self): 86 87 #数値設定 88 global roomNo 89 global room_reset_flag 90 91 #最大部屋番号ならカウントリセット 92 if roomNo == len(WINNUM_ARRAY): 93 room_reset_flag = True 94 95 #部屋番号の算出 96 if room_reset_flag: 97 roomNo = 1#True(リセットした)なら 98 room_reset_flag = False#旗を降ろす 99 else: 100 roomNo += 1#Falseなら 101 102 #再帰呼び出しの設定 103 #各部屋の制御窓数分の時間を確保 104 self.lblClock_hms.after(MAX_SEC*WINNUM_ARRAY[roomNo-1], self.Selectroom) 105 106 #各窓制御ルーチン 107 self.Selectwindow() 108 109 110 def Selectwindow(self):#各部屋表示値計算 111 112 #数値設定 113 global windowNo 114 global window_reset_flag 115 global after_id 116 117 #最大窓番号ならカウントリセット 118 if windowNo == WINNUM_ARRAY[int(roomNo)-1]: 119 window_reset_flag = True 120 self.lblClock_hms.after_cancel(after_id) 121 else: 122 #再帰呼び出し設定 123 after_id = self.lblClock_hms.after(MAX_SEC, self.Selectwindow) 124 125 if window_reset_flag: 126 windowNo = 1#True(リセットした)なら 127 window_reset_flag = False#旗を降ろす 128 else: 129 windowNo += 1 #Falseなら 130 131 #再描画 132 self.lblwindow_control_caption.destroy() 133 self.lblwindow_control_caption = customtkinter.CTkLabel(self.window_control_frame, text=str(roomNo)+"号室 No."+str(windowNo)+" 制御中") 134 self.lblwindow_control_caption.grid(row=0, column=0, padx=10, pady=(0, 0), sticky="nw",columnspan=2) 135 136 #デバッグ用 137 print("部屋番号:"+str(roomNo),",窓番号:"+str(windowNo)) 138 139if __name__ == "__main__": 140 141 #グローバル定数 142 WINNUM_ARRAY=[4,4,4,4,4,4,4]#各部屋の制御窓数を配列で保持 143 MAX_SEC=5000#最大窓制御時間[ms] 144 145 #グローバル変数 146 roomcount=0 147 windowcount=0 148 room_reset_flag=True 149 window_reset_flag=True 150 roomNo=0 151 windowNo=0 152 after_id=0 153 154 Disproom = Disproom() 155 Disproom.mainloop() 156
試したこと
プリントデバッグしたところ、
プログラム164行目にてafter_cancelをしたときに、次の窓に移行する時間が他より多くなりました。
聞きたいこと
after関数を使わずに、tkinterでforの二重ループを回して順番に表示させる方法があればご教示いただけませんか。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/07/14 08:03 編集
2023/07/14 10:01
2023/07/14 22:39
2023/07/15 14:16