Tkinter Label 绑定到 StringVar 更新时延迟一步

4 投票
1 回答
2204 浏览
提问于 2025-04-15 23:17

我遇到的问题是,当我点击Listbox中的不同文件名时,Label的显示值总是比我当前点击的文件名晚一步。

我漏掉了什么呢?

import Tkinter as tk

class TkTest: 

    def __init__(self, master):

        self.fraMain = tk.Frame(master)
        self.fraMain.pack()

        # Set up a list box containing all the paths to choose from
        self.lstPaths = tk.Listbox(self.fraMain)
        paths = [
            '/path/file1',
            '/path/file2',
            '/path/file3',
        ]
        for path in paths:
            self.lstPaths.insert(tk.END, path)
        self.lstPaths.bind('<Button-1>', self.update_label)
        self.lstPaths.pack()

        self.currentpath = tk.StringVar()
        self.lblCurrentPath = tk.Label(self.fraMain, textvariable=self.currentpath)
        self.lblCurrentPath.pack()

    def update_label(self, event):
        print self.lstPaths.get(tk.ACTIVE),
        print self.lstPaths.curselection()
        self.currentpath.set(self.lstPaths.get(tk.ACTIVE))

root = tk.Tk()
app = TkTest(root)
root.mainloop()

1 个回答

4

这个问题和Tk的基本设计有关。简单来说,就是特定控件上的绑定会在控件的默认类绑定之前触发。而在类绑定中,列表框的选择会被改变。这就是你观察到的现象——你看到的选择是在当前点击之前的状态。

最好的解决办法是绑定一个虚拟事件 <<ListboxSelect>>,这个事件是在选择改变之后触发的。还有其他解决方案(这些方案是Tk独有的,正是它强大和灵活的原因),就是修改绑定的应用顺序。这涉及到将控件的绑定标签移动到类绑定标签之后,或者在类绑定标签之后添加一个新的绑定标签,并将其绑定到那个。

因为绑定 <<ListboxSelect>> 是更好的解决方案,所以我就不详细讲怎么修改绑定标签了,实际上这很简单,而且文档也写得比较清楚。

撰写回答