tkinter Listbox绑定点击事件后获取的选中值不正确怎么办
Tkinter Listbox 选中值错位问题排查与修复
问题复现
以下测试代码运行时,点击列表选项后标签显示的选中值与实际点击项存在错位,无法正确获取用户选择:
from tkinter import * pencere = Tk() başlık = pencere.title("deneme2") etiket = Label(text="") etiket.pack() def göster(event): etiket["text"] = "%s seçildi."%liste.get(ACTIVE) etiket.pack() liste = Listbox() liste.insert(1, "İstanbul") liste.insert(2, "Ankara") liste.insert(3, "İzmir") liste.insert(4, "İzmit") liste.insert(5, "Antalya") liste.insert(6, "Bursa") liste.pack() liste.bind("<Button-1>",göster) mainloop()
具体错位表现:点击İzmir时显示İstanbul,点击Ankara时显示İstanbul,点击İstanbul时显示Ankara,所有返回值均和实际选择不匹配。
问题根因
代码中给Listbox绑定的<Button-1>事件会在鼠标左键按下的瞬间触发,此时Listbox内部的选中状态还未完成更新,回调里调用liste.get(ACTIVE)取到的是事件触发前留存的旧选中值,最终导致返回结果和实际点击项错位。
修复方法
两种方案二选一即可:
- 方案1(推荐):替换绑定事件为Tkinter列表框专用的
<<ListboxSelect>>虚拟事件,该事件只会在列表选中状态完全更新后触发,能稳定拿到最新选中值。 - 方案2:如果需要绑定鼠标操作,将事件替换为
<ButtonRelease-1>,即鼠标左键松开时触发回调,此时选中状态已经完成更新,也能拿到正确值。
修复后参考代码(采用方案1)
from tkinter import * pencere = Tk() pencere.title("deneme2") etiket = Label(text="") etiket.pack() def göster(event): # 多选场景下推荐用 liste.get(liste.curselection()[0]) 取值,兼容性更好 etiket["text"] = "%s seçildi."%liste.get(ACTIVE) liste = Listbox() liste.insert(1, "İstanbul") liste.insert(2, "Ankara") liste.insert(3, "İzmir") liste.insert(4, "İzmit") liste.insert(5, "Antalya") liste.insert(6, "Bursa") liste.pack() # 替换绑定事件为选中完成虚拟事件 liste.bind("<<ListboxSelect>>", göster) mainloop()
额外优化:原代码回调函数里重复调用
etiket.pack()没有必要,组件初始化完成布局后不需要重复调用布局方法。
内容的提问来源于stack exchange,提问作者NEHİR ERGAN
相关产品推荐
相关产品推荐

