Tkinter中Listbox绑定更新Label文本出现滞后点击问题
Tkinter Listbox点击后Label显示滞后的问题解决
你在Tkinter中实现了Listbox点击更新Label文本的功能,但遇到滞后问题:点击新的列表项时,Label显示的却是上一次选中的内容。例如点击项3后再点击项2,Label中显示的仍是项3。虽然在绑定函数中打印curselection()能得到正确的选中位置,但get(ACTIVE)却返回旧值。
问题代码
class MainWindow(ttk.Frame): def __init__(self, parent): super().__init__(parent) self.parent = parent self.parent.geometry(MAIN_GEOMETRY) self.parent.protocol("WM_DELETE_WINDOW", self.on_closing) self.standin_list = ["One", "Two", "Three", "Four", "Five"] self.titles_listbox = tk.Listbox(parent, width=80) self.titles_listbox.grid() self.titles_listbox.bind("<<ListboxSelect>>", self.update_label) self.fill_listbox() self.selected_label = tk.Label(parent, text="nothing selected...") self.selected_label.grid() def fill_listbox(self): self.update_listbox(self.standin_list) def update_listbox(self, formatted_titles_list): self.titles_listbox.delete(0, END) for item in formatted_titles_list: self.titles_listbox.insert(END, item) def update_label(self, event): print(self.titles_listbox.curselection()) self.selected_label.config(text=self.titles_listbox.get(ACTIVE))
问题原因
ACTIVE参数指向的是当前获得焦点的列表项,而<<ListboxSelect>>事件的触发时机早于焦点切换的时机,所以事件触发时ACTIVE仍然是上一次选中的项,导致获取的内容滞后。而curselection()直接返回当前实际选中的索引,不受焦点切换时机的影响,因此能得到正确结果。
解决方案
将get(ACTIVE)改为通过curselection()获取的索引来取值,修改后的update_label方法如下:
def update_label(self, event): selected_indices = self.titles_listbox.curselection() if selected_indices: # 处理无选中项的边界情况 index = selected_indices[0] self.selected_label.config(text=self.titles_listbox.get(index))
由于Listbox支持多选,curselection()返回的是索引元组,这里取第一个元素即可获取当前选中项的索引,再通过get(index)就能拿到实时的选中文本,解决滞后问题。
内容的提问来源于stack exchange,提问作者roxolid
相关产品推荐
相关产品推荐

