Python Tkinter Listbox 事件绑定
我在用python/tkinter的时候遇到了一些麻烦,想要绑定一个事件。我的目标很简单,就是点击一下,然后打印出点击的位置。但是每次我这么做的时候,结果都是“-1”。
这是我的代码:
from Tkinter import *
import Tkinter
class make_list(Tkinter.Listbox):
def __init__(self,master, **kw):
frame = Frame(master)
frame.pack()
self.build_main_window(frame)
kw['selectmode'] = Tkinter.SINGLE
Tkinter.Listbox.__init__(self, master, kw)
master.bind('<Button-1>', self.click_button)
master.curIndex = None
#display the clicked location
def click_button(self, event):
self.curIndex = self.nearest(event.x)
print self.curIndex
#display the window, calls the listbox
def build_main_window(self, frame):
self.build_listbox(frame)
#listbox
def build_listbox(self, frame):
listbox = Listbox(frame)
for item in ["one", "two", "three", "four"]:
listbox.insert(END, item)
listbox.insert(END, "a list entry")
listbox.pack()
return
if __name__ == '__main__':
tk = Tkinter.Tk()
make_list(tk)
tk.mainloop()
更新后的代码 - 我去掉了框架,但我还是搞不明白为什么在函数click_button里的第一个打印语句会得到-1。
from Tkinter import *
import Tkinter
class make_list(Tkinter.Listbox):
#display the clicked location
def click_button(self, event):
##this block works
w = event.widget
index = int(w.curselection()[0])
value = w.get(index)
print value
##this doesn't
self.curIndex = self.nearest(event.y)
print self.curIndex
self.curIndex = event.widget.nearest(event.y)
print self.curIndex
#display the window, calls the listbox
def build_main_window(self):
self.build_listbox()
#listbox
def build_listbox(self):
listbox = Listbox()
listbox.bind('<<ListboxSelect>>', self.click_button)
for item in ["one", "two", "three", "four"]:
listbox.insert(END, item)
listbox.insert(END, "a list entry")
listbox.pack()
return
if __name__ == '__main__':
tk = Tkinter.Tk()
start = make_list(tk)
start.build_main_window()
start.mainloop()
2 个回答
6
在某个回答的评论里,你问到了最佳做法。最佳做法是绑定到 <<ListboxSelect>>
事件,这个事件会在你选择列表框中的某个项目后立即触发。
这个回答提供了一个类似问题的例子。
3
在这个列表框中,最近的项目是通过 y
坐标找到的,而不是 x
坐标。
self.nearest(event.x) # wrong
self.nearest(event.y) # right
更新:我一开始没有注意到真正的问题:
listbox = Listbox(frame)
你使用的并不是你自己创建的那个列表框,而是另一个无关的列表框。你的列表框(也就是 make_list)是空的,所以它总是返回 -1,表示没有找到最近的项目。
也许把一个框架(frame)进行子类化是个好主意(总之,这比把列表框子类化再在里面加一个列表框要好)。这样你就需要在那个真实的非空列表框上绑定事件。
想快速看看修复后会怎样,可以用 event.widget
调用一个真实列表框的 nearest
方法:
self.curIndex = event.widget.nearest(event.y)