如何绑定"选择所有"列表框上的事件?

时间:2015-01-20 21:30:44

标签: python python-2.7 listbox tkinter bind

我有两个列表框。选择一个列表框时,它会使用函数的输出触发结束更新。当我使用<<ListboxSelect>>事件单独单击每个选项时,这可以正常工作,但我现在不知道如何使用全选按钮。全部选择按钮用于突出显示项目,但我无法更新第二个列表。

评论来自previous question

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

2 个答案:

答案 0 :(得分:4)

您的select_all_drives功能可以触发事件:

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

答案 1 :(得分:2)

您可以重复使用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

然后在get_selected_filesonSelect方法中调用select_all_drives

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