更改 Tkinter 列表框选择时获取回调?

Posted

技术标签:

【中文标题】更改 Tkinter 列表框选择时获取回调?【英文标题】:Getting a callback when a Tkinter Listbox selection is changed? 【发布时间】:2011-09-27 03:25:13 【问题描述】:

TextEntry 小部件在 Tkinter 中更改时,有多种方法可以获取回调,但我还没有找到 Listbox 的一种(它对事件没有多大帮助我能找到的文档是旧的或不完整的)。有什么方法可以为此生成事件吗?

【问题讨论】:

所有虚拟活动都列在:The Tcl/Tk man pages。 【参考方案1】:
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)

lb = Listbox(frame, name='lb')
lb.bind('<<ListboxSelect>>', onselect)

【讨论】:

次要点,但这仅打印所选条目中的第一个。如果您有多项选择,请尝试print 'You selected items: %s'%[w.get(int(i)) for i in w.curselection()] 在 Python 3.6.5 中,int(w.curselection()[0]) 可以替换为 w.curselection()[0],因为它已经返回了一个 int 类型的对象。请注意,我没有尝试使用任何其他 Python 版本。【参考方案2】:

您可以绑定到&lt;&lt;ListboxSelect&gt;&gt; 事件。在选择变化时,将生成此事件,无论它是否从按钮,通过键盘或任何其他方法都会从按钮中更改。

这是一个简单的例子,当你从列表框中选择一些东西时,它会更新一个标签:

import tkinter as tk

root = tk.Tk()
label = tk.Label(root)
listbox = tk.Listbox(root)
label.pack(side="bottom", fill="x")
listbox.pack(side="top", fill="both", expand=True)

listbox.insert("end", "one", "two", "three", "four", "five")

def callback(event):
    selection = event.widget.curselection()
    if selection:
        index = selection[0]
        data = event.widget.get(index)
        label.configure(text=data)
    else:
        label.configure(text="")

listbox.bind("<<ListboxSelect>>", callback)

root.mainloop()

规范的man page for listbox 中提到了此事件。所有预定义的虚拟事件都可以在bind man page 上找到。

【讨论】:

完美,谢谢。知道在哪里可以找到有关小部件支持的所有自定义事件的文档吗? @RobotGymnast 尝试(Tcl/Tk 手册页)[tcl.tk/man/tcl8.5/TkCmd/event.htm#M41](来自下面比尔的回答)【参考方案3】:

我遇到的问题是我需要使用 selectmode=MULTIPLE 获取列表框中的最后一个选定项目。如果其他人有同样的问题,这就是我所做的:

lastselectionList = []
def onselect(evt):
    # Note here that Tkinter passes an event object to onselect()
    global lastselectionList
    w = evt.widget
    if lastselectionList: #if not empty
    #compare last selectionlist with new list and extract the difference
        changedSelection = set(lastselectionList).symmetric_difference(set(w.curselection()))
        lastselectionList = w.curselection()
    else:
    #if empty, assign current selection
        lastselectionList = w.curselection()
        changedSelection = w.curselection()
    #changedSelection should always be a set with only one entry, therefore we can convert it to a lst and extract first entry
    index = int(list(changedSelection)[0])
    value = w.get(index)
    tkinter.messagebox.showinfo("You selected ", value)
listbox = tk.Listbox(frame,selectmode=tk.MULTIPLE)
listbox.bind('<<ListboxSelect>>', onselect)
listbox.pack()

【讨论】:

以上是关于更改 Tkinter 列表框选择时获取回调?的主要内容,如果未能解决你的问题,请参考以下文章

更改 tkinter 列表框中的项目顺序

使用箭头键滚动的 Tkinter 列表框

我可以双击 tkinter 列表框选项来调用 Python 中的函数吗?

tkinter窗口系列之一——列表框

tkinter 列表框用 python 拖放

如何在 Tkinter 列表框中插入时添加自动滚动?