首页 文章

在列表框中获取所选项目并调用另一个存储所选项目的函数

提问于
浏览
4

我有一个在单击时调用 createCategoryMeny(x) 的画布 .

这个函数只创建一个 Toplevel() 窗口,

def createCategoryMenu(tableNumber):

    ##Not interesting below:
    categoryMenu = Toplevel()
    categoryMenu.title("Mesa numero: " + str(tableNumber))
    categoryMenu.geometry("400x400+100+100")

    categoryMenu.focus()
    categoryMenu.grab_set()

    Label(categoryMenu, text="Elegir categoria \n Mesa numero: " + str(tableNumber)).pack()


    ## RELEVANT CODE BELOW:
    listbox = Listbox(categoryMenu, width=50, height=len(info.listaCategorias))
    listbox.pack(pady=20)

    for item in info.listaCategorias:
        listbox.insert(END, item)

    listbox.selection_set(first=0)

    ##My attempt to solve it
    callback = lambda event, tag= "ThisShouldBeTheSelected!!": do(event, tag)
    listbox.bind("<Double-Button-1>", callback)

那么do函数:

def do(event, tag):
    print tag

这成功地打印了“ThisShouldBeTheSelected !!”`` .

这就是我完全陷入困境的地方 .

我无法获得双击元素(选定的元素) .

我想把它传递给 tag= .

我试过了:

listbox.curselection()

总是打印 ('0',)

如果我删除 listbox.selection_set(first=0) ,我只能得到这个: ()

所以问题是:

  • 如何获取所选项目(双击一项)

  • (不是那么重要)将它传递给我的其他函数是否合理?


注意:

我找到this

8.5 . 当我将一个按钮绑定到我的列表框时,为什么没有.listbox curselection或selection返回正确的项目?在列表框上的按钮单击事件期间获取所选项目的最佳方法是使用以下代码:bind .listbox {set item [%W get [%W nearest%y]]}这确保指针下的项目是作为项目返回的内容 . .listbox curselection失败的原因是因为在Listbox类绑定触发器之前未设置curselection中的项目,这是在默认情况下实例绑定之后 . 这与选择get失败的原因相同,但如果将-exportselection选项设置为0,它也将失败 .

我不确定它是否有用,我真的不明白它的含义 .

3 回答

  • 13

    首先,不要使用 lambda . 它是其中之一 . 创建一个合适的函数,它们更容易编写和维护 .

    完成后,您可以调用 curselection 来获取当前选择 . 你说你试过,但你的示例代码没有显示你尝试过的,所以我只能假设你做错了 .

    至于使用 nearest 的相当不同寻常的建议...所有它说的是你放在一个小部件上的绑定发生在同一事件的默认绑定之前 . 它是设置选择的默认绑定,因此当您绑定到单个按钮单击时,绑定将在默认绑定更新选择之前触发 . 有很多方法,其中最好的方法是不单击一次绑定,而是绑定在 <<ListboxSelect>> 上,这将在选择发生变化后触发 .

    但是,你没有这个问题 . 由于您在双击时绑定,因此选择将由默认的单击绑定设置, curselection 将返回正确的值 . 也就是说,除非您有自己的单击绑定,否则会阻止默认绑定触发 .

    这是一个打印出选择的简单示例,因此您可以看到它是正确的 . 从命令行运行它,以便您看到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

    对于spyder和python 3.6,以下代码有效 .

    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

    虽然你只有一个要管理的列表框,但使用这样的东西(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()
    

    但是当您添加另一个列表框或\并遇到情况时,listbox会丢失其选择,会引发IndexError . 为避免它,并管理不同列表框的不同回调,我建议这样的事情:

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

相关问题