139 lines · 3.9 KB · Python
RawDownload
from Tkinter import * class ScrolledList:     default = "(None)"     def __init__(self, master, **options):        # Create top frame, with scrollbar and listbox        self.master = master        self.frame = frame = Frame(master)        self.frame.pack(fill="both", expand=1)        self.vbar = vbar = Scrollbar(frame, name="vbar")        self.vbar.pack(side="right", fill="y")        self.listbox = listbox = Listbox(frame, exportselection=0,            background="white")        if options:            listbox.configure(options)        listbox.pack(expand=1, fill="both")        # Tie listbox and scrollbar together        vbar["command"] = listbox.yview        listbox["yscrollcommand"] = vbar.set        # Bind events to the list box        listbox.bind("<ButtonRelease-1>", self.click_event)        listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)        listbox.bind("<ButtonPress-3>", self.popup_event)        listbox.bind("<Key-Up>", self.up_event)        listbox.bind("<Key-Down>", self.down_event)        # Mark as empty        self.clear()     def close(self):        self.frame.destroy()     def clear(self):        self.listbox.delete(0, "end")        self.empty = 1        self.listbox.insert("end", self.default)     def append(self, item):        if self.empty:            self.listbox.delete(0, "end")            self.empty = 0        self.listbox.insert("end", str(item))     def get(self, index):        return self.listbox.get(index)     def click_event(self, event):        self.listbox.activate("@%d,%d" % (event.x, event.y))        index = self.listbox.index("active")        self.select(index)        self.on_select(index)        return "break"     def double_click_event(self, event):        index = self.listbox.index("active")        self.select(index)        self.on_double(index)        return "break"     menu = None     def popup_event(self, event):        if not self.menu:            self.make_menu()        menu = self.menu        self.listbox.activate("@%d,%d" % (event.x, event.y))        index = self.listbox.index("active")        self.select(index)        menu.tk_popup(event.x_root, event.y_root)     def make_menu(self):        menu = Menu(self.listbox, tearoff=0)        self.menu = menu        self.fill_menu()     def up_event(self, event):        index = self.listbox.index("active")        if self.listbox.selection_includes(index):            index = index - 1        else:            index = self.listbox.size() - 1        if index < 0:            self.listbox.bell()        else:            self.select(index)            self.on_select(index)        return "break"     def down_event(self, event):        index = self.listbox.index("active")        if self.listbox.selection_includes(index):            index = index + 1        else:            index = 0        if index >= self.listbox.size():            self.listbox.bell()        else:            self.select(index)            self.on_select(index)        return "break"     def select(self, index):        self.listbox.focus_set()        self.listbox.activate(index)        self.listbox.selection_clear(0, "end")        self.listbox.selection_set(index)        self.listbox.see(index)     # Methods to override for specific actions     def fill_menu(self):        pass     def on_select(self, index):        pass     def on_double(self, index):        pass  def test():    root = Tk()    root.protocol("WM_DELETE_WINDOW", root.destroy)    class MyScrolledList(ScrolledList):        def fill_menu(self): self.menu.add_command(label="pass")        def on_select(self, index): print "select", self.get(index)        def on_double(self, index): print "double", self.get(index)    s = MyScrolledList(root)    for i in range(30):        s.append("item %02d" % i)    return root def main():    root = test()    root.mainloop() if __name__ == '__main__':    main()