Tkinter 列表框的“selection_set”和“activate”暂时禁用扩展选择

acd*_*cdr 4 python tkinter

TkinterListbox可以允许通过selectmode配置选择多个项目。但是,如果我现在以编程方式选择并激活一个条目,则将 Shift 键与向上或向下箭头键组合使用不会将选择范围扩展到当前项目上方/下方的项目,而只会激活该新项目,同时保留旧的选择。

例如,在以下 (Python 2.7) 代码中,我进行了子类化Listbox,以允许 Home 和 End 键分别选择列表中的第一项和最后一项:

import Tkinter as tk

class MyListbox(tk.Listbox):
    def __init__(self, *args, **kwargs):
        tk.Listbox.__init__(self, *args, **kwargs)
        self.bind("<Home>", lambda *args: self.select(0))
        self.bind("<End>", lambda *args: self.select("end"))

    def select(self, index):
        self.select_clear(0, "end")
        self.selection_set(index)
        self.see(index)
        self.activate(index)

main = tk.Tk()
listbox = MyListbox(main, selectmode="extended")
for x in ["one", "two", "three", "four", "five"]:
    listbox.insert("end", x)
listbox.pack()

tk.mainloop()
Run Code Online (Sandbox Code Playgroud)

这会产生一个窗口,其中有一个列表框。如果选择列表框并单击“结束”,则会选择最后一个元素(字符串“五”)。如果您现在按 Shift-Up,那么您会期望选择字符串“four”和“ Five”。相反,“四”在没有被选择的情况下被激活(如预期),并且“五”保持选中状态。

为什么除了“五”之外,没有选择“四”?我可以解决这个问题而不必重新绑定箭头键和朋友吗?

请注意,如果我通过单击某个项目或使用箭头键导航到该项目来选择该项目,则不会发生此行为。

Bry*_*ley 5

您还需要通过在方法内部调用来设置锚点self.selection_anchor(index)select

def select(self, index):
    self.select_clear(0, "end")
    self.selection_set(index)
    self.see(index)
    self.activate(index)
    self.selection_anchor(index)
Run Code Online (Sandbox Code Playgroud)