【问题标题】:getting event late in tkinter listbox [duplicate]在tkinter列表框中迟到事件[重复]
【发布时间】:2021-08-18 12:21:46
【问题描述】:

我正在创建包含从 0 到 9 的数字的简单列表框。我想在单击它时打印数字,因此我将列表框与 Button-1 绑定。我面临的问题是,当我选择任何数字并尝试使用list_box.curselection() 获取其位置时,它不会打印任何东西(返回空元组),如果我单击任何其他数字,它就会打印之前选择的数字。我想获取当前选择的号码。

from tkinter import *
root = Tk()
root.title("test listbox")


list_box = Listbox(root)
list_box.pack()
for i in range(0,10):
    list_box.insert("end",i)

def def_fun(event):
    print(list_box.curselection())
list_box.bind("<Button-1>",def_fun)
root.mainloop()

【问题讨论】:

  • 您好,非常感谢您标记答案

标签: python tkinter


【解决方案1】:

您不必绑定到&lt;Button-1&gt; 或任何东西,您可以在这里使用Listbox 的虚拟事件:

def def_fun(event):
    print(event.widget.curselection()) # The widget that triggers the event is event.widget

list_box.bind("<<ListboxSelect>>",def_fun) # Gets triggered each time something is selected

如果你想知道为什么Button-1 不起作用,那是因为有延迟,延迟可能是由于绑定顺序,你可以阅读更多关于它here 但这里有一个要点:

在默认情况下,&lt;Key&gt; 上的绑定发生在类绑定之前,它是文本实际插入小部件的类绑定。这就是为什么你的绑定似乎总是落后一个字符。

【讨论】:

    【解决方案2】:

    将绑定更改为释放鼠标按钮,这也将更加用户友好(例如,如果他们不小心点击了他们不想选择的选择,他们可以将鼠标移动到他们想要的地方并且只有释放才会调用函数):

    from tkinter import Tk, Listbox
    
    
    def def_fun(event=None):
        print(list_box.curselection())
    
    
    root = Tk()
    root.title("test listbox")
    
    list_box = Listbox(root)
    list_box.pack()
    for i in range(0, 10):
        list_box.insert("end", i)
    
    list_box.bind("<ButtonRelease-1>", def_fun)
    root.mainloop()
    

    如果您想在 select 上调用该函数,另一个选项是使用 @CoolCloud 答案,或者您也可以设置这样的延迟(尽管它肯定会在 99.9% 的情况下工作,但可能存在这样的情况't):

    list_box.bind("<Button-1>", lambda e: root.after(10, def_fun))
    

    原因是 .curselection() 获取当前选择,但 Button-1 在任何内容被选择之前被触发,因此它将打印上一个选择,因为这是之前选择的内容和当前选择的位置,然后是紧随其后这样,它会将当前选择移动到您单击的项目。

    重要(因为它可能会导致难以调试的问题):
    我强烈建议在导入某些内容时不要使用通配符 (*),您应该导入您需要的内容,例如from module import Class1, func_1, var_2 等等或导入整个模块:import module 然后你也可以使用别名:import module as md 或类似的东西,关键是不要导入所有内容,除非你真的知道你在做什么;名称冲突是问题所在。

    还有:
    我强烈建议关注PEP 8 - Style Guide for Python Code。函数和变量名应该在snake_case,类名在CapitalCase。如果= 用作关键字参数的一部分(func(arg='value')),则不要在= 周围留有空格,但如果它用于分配值(variable = 'some value'),则使用它。在函数和类声明周围有两个空行。

    【讨论】:

    • thankyou 为我工作,也感谢您对代码编写的建议,我很感激。
    猜你喜欢
    • 2013-01-06
    • 2017-07-15
    • 2021-11-30
    • 1970-01-01
    • 2013-04-01
    • 2015-11-24
    • 2021-01-24
    • 2021-07-13
    • 2020-06-05
    相关资源
    最近更新 更多