我正在创建一个简单的列表框,其中包含从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()
您不必绑定到<Button-1>
或任何东西,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
为什么不起作用,那是因为有延迟,延迟可能是由于绑定订单,你可以在这里阅读更多信息,但这里有一个要点:
在默认情况下,
<Key>
上的绑定发生在类绑定之前,并且它是文本实际插入小部件的类绑定。这就是为什么你的绑定似乎总是落后一个字符。
将绑定更改为释放鼠标按钮,这也将更加用户友好(例如,如果他们不小心点击了不想选择的选项,他们可以将鼠标移动到他们想要的位置,只有释放才会调用该函数):
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%的情况下肯定会起作用,但也有可能不起作用):
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-Python代码风格指南。函数名和变量名应在snake_case
中,类名应在CapitalCase
中。如果=
用作关键字参数(func(arg='value')
)的一部分,则其周围没有空格,但如果用于赋值(variable = 'some value'
),则使用。在函数和类声明周围有两行空白。