如何在列表框上绑定 "select all" 事件?

How to bind a "select all" event on a listbox?

我有两个列表框。当一个列表框被 selected 时,它会触发结束以使用函数的输出进行更新。当我使用 <<ListboxSelect>> 事件分别单击每个选项时效果很好,但是我现在不知道如何让它与 select 全部按钮一起使用。 select all 按钮在突出显示项目方面有效,但我无法使用它来更新第二个列表。

评论来自

from Tkinter import *



# dummy list so that the code does not relay on actually drives and files
rdrive = ['drive1','drive2','drive3']

sel_files = {'drive1': ['file1','file2'],
                  'drive2': ['file3','file4'],
                  'drive3': ['file6','file5']}

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("Listbox")
        self.pack(fill=BOTH, expand=1)

        # Drive Select List Box
        # global rdrive
        # rdrive = drive_ctypes.find_rmdrv()            

        # use dummy rdrive instead of physical drives. Otherwise,
        # cant reproduce the problem.  

        self.lb = Listbox(self, height=10, selectmode=MULTIPLE)
        for i in rdrive:
            self.lb.insert(END, i)

        self.lb.bind("<<ListboxSelect>>", self.onSelect)

        self.lb.grid(row =3, column =2)

        self.drives_select_b = Button(self, text = "Select All", command = self.select_all_drives)
        #self.drives_select_b.bind("<Button-1>", PLACE HOLDER)
        self.drives_select_b.grid(row =4, column =3)

        ## File Select List Box
        self.flb = Listbox(self, height=10, selectmode=MULTIPLE)

        self.flb.grid(row =3, column =4)


    def onSelect(self, event):
        # most changes are here. GUI programming is event driven, so you need
        # to get the list of files for selected drive (i.e. when selection even occurs).
        # Also here you respond the the even, so that the right list is populated.


        # get widget (i.e. right listbox) and currently selected item(s) 
        widget = event.widget
        selection=widget.curselection()

        files_avalibe = []

        # if something was selected, than get drives for which it was selected
        # and retrieve files for each drive
        if selection:


            for drive_i in selection:
                selected_drive = rdrive[drive_i]
                files_avalibe += sel_files[selected_drive]


            print(files_avalibe)

        # once we have files from the selected drive, list them 
        # in the right list box 
        self.update_file_list(files_avalibe)



    def update_file_list(self, file_list):
          # updates right listbox
          self.flb.delete(0, END)
          for i in file_list:
            self.flb.insert(END, i)


    def select_all_drives(self):
        self.lb.select_set(0, END)






root = Tk()
f = Example(root)
root.mainloop()

您可以重复使用 onSelect 方法中的代码。您需要做的就是将 event.widget 替换为 self.lb:

def select_all_drives(self):
    self.lb.select_set(0, END)
    selection=self.lb.curselection()
    files_avalibe = []
    if selection:
        for drive_i in selection:
            selected_drive = rdrive[drive_i]
            files_avalibe += sel_files[selected_drive]
    self.update_file_list(files_avalibe)

当然,这有点重复(两种方法的代码相同)。最好将其分解为一个单独的方法:

def get_selected_files(self):
    selection=self.lb.curselection()
    files_avalibe = []
    if selection:
        for drive_i in selection:
            selected_drive = rdrive[drive_i]
            files_avalibe += sel_files[selected_drive]
    return files_avalibe

然后在onSelectselect_all_drives方法中调用get_selected_files

def onSelect(self, event):
    self.update_file_list(self.get_selected_files())

...

def select_all_drives(self):
    self.lb.select_set(0, END)
    self.update_file_list(self.get_selected_files())

您的select_all_drives函数可以触发事件:

def select_all_drives(self):
    self.lb.select_set(0, END)
    self.lb.event_generate("<<ListboxSelect>>")