更新时绑定到StringVar的Tkinter Label落后一键

Posted

技术标签:

【中文标题】更新时绑定到StringVar的Tkinter Label落后一键【英文标题】:Tkinter Label bound to StringVar is one click behind when updating 【发布时间】:2011-02-25 05:46:18 【问题描述】:

我在这里遇到的问题是,当我单击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】:

问题与 Tk 的基本设计有关。简短的版本是,特定小部件上的绑定在小部件的默认类绑定之前触发。它是在类绑定中更改列表框的选择。这正是您所观察到的——您看到的是当前点击之前的选择。

最好的解决方案是绑定到虚拟事件&lt;&lt;ListboxSelect&gt;&gt;,该事件在选择更改后触发。其他解决方案(Tk 独有的以及赋予它一些令人难以置信的功能和灵活性的原因)是修改应用绑定的顺序。这涉及将小部件绑定标签移动到类绑定标签之后,或者在类绑定标签之后添加一个新的绑定标签并将其绑定到该类。

由于绑定到&lt;&lt;ListboxSelect&gt;&gt; 是更好的解决方案,因此我不会详细介绍如何修改绑定标签,尽管它很简单,而且我认为有据可查。

【讨论】:

成功了,谢谢!在我阅读的教程中,我没有看到任何对 > 的引用,甚至在谷歌上搜索那个确切的词似乎也没有提供太多信息。是否有所有虚拟事件的列表?这在 Tk 中似乎真的是一个令人讨厌的“陷阱”...... @Sam:没有所有事件的单一列表。 Tk 手册页列出了该小部件手册页上每个小部件的事件。因此,例如,> 列在此处的列表框手册页中:tcl.tk/man/tcl8.4/TkCmd/listbox.htm

以上是关于更新时绑定到StringVar的Tkinter Label落后一键的主要内容,如果未能解决你的问题,请参考以下文章

用python的Tkinter中的按钮,绑定的事件如何更改全局变量的问题

Tkinter StringVar 获取所选选项的索引

ValueError:无效的文件路径或缓冲区对象类型:<class 'tkinter.StringVar'>

Python/Tkinter:Tkinter StringVar(IntVar 等)线程安全吗?

使用 Tkinter 按下按钮后更新标签 [重复]

TKinter Scale