python tkinter listbox event binding

半世苍凉 提交于 2019-12-04 06:01:51

问题


I'm having trouble getting an event binding to work with python/tkinter. I'm simply trying to click and have the location printed, but every time I do this, "-1" is the result.

Here's my code

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()

updated code - I got rid of frame but I can't seem to figure out why I'm getting -1 for the first print statement in the function click_button

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()

回答1:


listbox nearest item is found by y, not x.

 self.nearest(event.x)     # wrong
 self.nearest(event.y)     # right

Update: I didn't notice the real problem first:

    listbox = Listbox(frame)

It's not the same listbox which you subclassed, it's another unrelated listbox. Your listbox (which is make_list) is empty, that's why it always returns -1 for nearest.

Perhaps subclassing a frame is a good idea (anyway, better than subclassing listbox and adding a frame with another listbox into it). Then you'll have to bind event on that real listbox which is not empty.

Quick way to see how it will work when fixed is to call nearest of a real listbox with event.widget:

self.curIndex = event.widget.nearest(event.y)



回答2:


In the comments of an answer you ask for the best practice. The best practice is to bind to <<ListboxSelect>> which will fire immediately after the item is selected in the listbox.

This answer to a similar question has an example.



来源:https://stackoverflow.com/questions/14467604/python-tkinter-listbox-event-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!