Get selected item in listbox and call another function storing the selected for it

前端 未结 3 1167
不知归路
不知归路 2020-12-19 10:53

I have a canvas that calls createCategoryMeny(x) when it is clicked.

This function just creates a Toplevel() window,

def cr         


        
相关标签:
3条回答
  • 2020-12-19 11:17

    For one, don't use lambda. It's useful for a narrow range of problems and this isn't one of them. Create a proper function, they are much easier to write and maintain.

    Once you do that, you can call curselection to get the current selection. You say you tried that but your example code doesn't show what you tried, so I can only assume you did it wrong.

    As for the rather unusual advice to use nearest... all it's saying is that bindings you put on a widget happen before default bindings for that same event. It is the default bindings that set the selection, so when you bind to a single button click, your binding fires before the selection is updated by the default bindings. There are many ways around that, the best of which is to not bind on a single click, but instead bind on <<ListboxSelect>> which will fire after the selection has changed.

    You don't have that problem, however. Since you are binding on a double-click, the selection will have been set by the default single-click binding and curselection will return the proper value. That is, unless you have your own single-click bindings that prevent the default binding from firing.

    Here's a simple example that prints out the selection so you can see it is correct. Run it from the command line so you see stdout:

    import Tkinter as tk
    
    class SampleApp(tk.Tk):
        def __init__(self, *args, **kwargs):
            tk.Tk.__init__(self, *args, **kwargs)
            lb = tk.Listbox(self)
            lb.insert("end", "one")
            lb.insert("end", "two")
            lb.insert("end", "three")
            lb.bind("<Double-Button-1>", self.OnDouble)
            lb.pack(side="top", fill="both", expand=True)
    
        def OnDouble(self, event):
            widget = event.widget
            selection=widget.curselection()
            value = widget.get(selection[0])
            print "selection:", selection, ": '%s'" % value
    
    if __name__ == "__main__":
        app = SampleApp()
        app.mainloop()
    
    0 讨论(0)
  • 2020-12-19 11:19

    For spyder and python 3.6 this following code worked.

    import tkinter as tk
    root = tk.Tk()
    root.geometry("612x417")
    root.title("change label on listbox selection")
    root.resizable(0,0)
    root.configure(background='lightgrey')
    
    
    #Show selected currency for from in label
    frmcur_text = tk.StringVar()
    frmcur = tk.Label(root, textvariable=frmcur_text, font="Helvetica 10 bold", anchor='w', background='lightgrey').place(x=195,y=50)
    
    def onselect(evt):
        # Note here that Tkinter passes an event object to onselect()
    
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
    #    print ('You selected item %d: "%s"' % (index, value))
        frmcur_text.set(value)
    
    #Create listboxes for xurrency selection
    listbox1 = tk.Listbox(root, font="Helvetica 11 bold", height=3, width=10)
    listbox2 = tk.Listbox(root, font="Helvetica 11 bold", height=3, width=10)
    listbox1.place(x=300,y=50)
    listbox2.place(x=300,y=125)
    
    
    for i in range(20):
        i = i + 1
        listbox1.insert(1, i)
        listbox2.insert(1, i)
    
    
    listbox1.bind('<<ListboxSelect>>', onselect)    
    
    cs = listbox1.curselection()
    
    frmcur_text.set(cs)
    
    root.mainloop()
    
    0 讨论(0)
  • 2020-12-19 11:22

    While You have only one listbox to manage with, it's quite good to use something like this (Python 3):

    import tkinter as tk
    
    root = tk.Tk()
    box = tk.Listbox(root)
    box.insert(tk.END, 'First')
    box.insert(tk.END, 'Second')
    box.insert(tk.END, 'Third')
    box.pack()
    
    
    def onselect(event):
        w = event.widget
        idx = int(w.curselection()[0])
        value = w.get(idx)
        print(value)
    
    
    box.bind('<<ListboxSelect>>', onselect)
    
    root.mainloop()
    

    But when You add another listbox, or\and meet a situation, where listbox loses its selection, IndexError is raised. To avoiding it, and to manage different callbacks for different listboxes I suggest something like this:

    import tkinter as tk
    
    root = tk.Tk()
    box = tk.Listbox(root)
    box.insert(tk.END, 'First')
    box.insert(tk.END, 'Second')
    box.insert(tk.END, 'Third')
    box.pack()
    
    box2 = tk.Listbox(root)
    box2.insert(tk.END, 'First')
    box2.insert(tk.END, 'Second')
    box2.insert(tk.END, 'Third')
    box2.pack()
    
    
    def on_first_box(idx, val):
        print('First box idx: %s, value: %s' % (idx, val))
    
    
    def on_second_box(idx, val):
        print('Second box idx: %s, value: %s' % (idx, val))
    
    
    def onselect(event, listbox):
        w = event.widget
        try:
            idx = int(w.curselection()[0])
        except IndexError:
            return
        if listbox is box:
            return on_first_box(idx, w.get(idx))
        if listbox is box2:
            return on_second_box(idx, w.get(idx))
    
    
    box.bind('<<ListboxSelect>>', lambda e: onselect(e, box))
    box2.bind('<<ListboxSelect>>', lambda e: onselect(e, box2))
    
    root.mainloop()
    
    0 讨论(0)
提交回复
热议问题