如何识别Tkinter/CustomTkinter批量创建的开关中最新切换的控件
批量CTkSwitch获取最新切换控件的高效解决方案
方案1:通过Lambda为Command传递控件索引/对象
直接在创建开关时,用lambda将当前循环的索引或控件对象绑定到回调函数的参数中,触发时即可直接获取目标开关,无需额外状态对比:
修改创建开关的代码:
with open(r"D:\Largecodefile\TkinterApply\List1.txt",'r') as f: Lines=f.read().splitlines() for i,val in enumerate(Lines): switch = ct.CTkSwitch(master=self.scrollable_framel, text=val, # 绑定当前索引和开关对象到lambda参数 command=lambda idx=i, sw=switch: self.changestate(idx, sw)) switch.grid(row=i, column=0, padx=10, pady=(0, 20)) self.scrollable_frame_switches.append(switch)
对应的回调函数实现:
def changestate(self, idx, switch): # idx为开关在列表中的索引,switch为控件实例 print(f"最新切换的开关:索引{idx},文本「{switch.cget('text')}」") print(f"当前状态:{'开启' if switch.get() else '关闭'}") # 在此编写后续操作逻辑
注意:lambda参数中必须写成
idx=i而非直接使用i,否则所有lambda都会引用循环结束后的最终i值,导致索引错误。
方案2:绑定鼠标释放事件获取触发控件
通过绑定<ButtonRelease-1>事件,利用事件对象直接获取触发操作的开关控件,无需提前传递参数:
创建开关时绑定事件:
with open(r"D:\Largecodefile\TkinterApply\List1.txt",'r') as f: Lines=f.read().splitlines() for i,val in enumerate(Lines): switch = ct.CTkSwitch(master=self.scrollable_framel, text=val) switch.grid(row=i, column=0, padx=10, pady=(0, 20)) # 绑定鼠标释放事件到回调函数 switch.bind("<ButtonRelease-1>", self.on_switch_toggle) self.scrollable_frame_switches.append(switch)
回调函数实现:
def on_switch_toggle(self, event): # event.widget即为触发事件的开关控件 target_switch = event.widget # 从列表中获取控件索引 switch_idx = self.scrollable_frame_switches.index(target_switch) print(f"最新切换的开关:索引{switch_idx},文本「{target_switch.cget('text')}」") print(f"当前状态:{'开启' if target_switch.get() else '关闭'}") # 在此编写后续操作逻辑
以上两种方案均无需对比全局状态列表,也无需为每个开关创建独立函数,无论列表长度多少都能高效定位到最新操作的开关。
内容的提问来源于stack exchange,提问作者V21
相关产品推荐
相关产品推荐

