Home | History | Annotate | Download | only in idlelib
      1 from Tkinter import *
      2 
      3 class ScrolledList:
      4 
      5     default = "(None)"
      6 
      7     def __init__(self, master, **options):
      8         # Create top frame, with scrollbar and listbox
      9         self.master = master
     10         self.frame = frame = Frame(master)
     11         self.frame.pack(fill="both", expand=1)
     12         self.vbar = vbar = Scrollbar(frame, name="vbar")
     13         self.vbar.pack(side="right", fill="y")
     14         self.listbox = listbox = Listbox(frame, exportselection=0,
     15             background="white")
     16         if options:
     17             listbox.configure(options)
     18         listbox.pack(expand=1, fill="both")
     19         # Tie listbox and scrollbar together
     20         vbar["command"] = listbox.yview
     21         listbox["yscrollcommand"] = vbar.set
     22         # Bind events to the list box
     23         listbox.bind("<ButtonRelease-1>", self.click_event)
     24         listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
     25         listbox.bind("<ButtonPress-3>", self.popup_event)
     26         listbox.bind("<Key-Up>", self.up_event)
     27         listbox.bind("<Key-Down>", self.down_event)
     28         # Mark as empty
     29         self.clear()
     30 
     31     def close(self):
     32         self.frame.destroy()
     33 
     34     def clear(self):
     35         self.listbox.delete(0, "end")
     36         self.empty = 1
     37         self.listbox.insert("end", self.default)
     38 
     39     def append(self, item):
     40         if self.empty:
     41             self.listbox.delete(0, "end")
     42             self.empty = 0
     43         self.listbox.insert("end", str(item))
     44 
     45     def get(self, index):
     46         return self.listbox.get(index)
     47 
     48     def click_event(self, event):
     49         self.listbox.activate("@%d,%d" % (event.x, event.y))
     50         index = self.listbox.index("active")
     51         self.select(index)
     52         self.on_select(index)
     53         return "break"
     54 
     55     def double_click_event(self, event):
     56         index = self.listbox.index("active")
     57         self.select(index)
     58         self.on_double(index)
     59         return "break"
     60 
     61     menu = None
     62 
     63     def popup_event(self, event):
     64         if not self.menu:
     65             self.make_menu()
     66         menu = self.menu
     67         self.listbox.activate("@%d,%d" % (event.x, event.y))
     68         index = self.listbox.index("active")
     69         self.select(index)
     70         menu.tk_popup(event.x_root, event.y_root)
     71 
     72     def make_menu(self):
     73         menu = Menu(self.listbox, tearoff=0)
     74         self.menu = menu
     75         self.fill_menu()
     76 
     77     def up_event(self, event):
     78         index = self.listbox.index("active")
     79         if self.listbox.selection_includes(index):
     80             index = index - 1
     81         else:
     82             index = self.listbox.size() - 1
     83         if index < 0:
     84             self.listbox.bell()
     85         else:
     86             self.select(index)
     87             self.on_select(index)
     88         return "break"
     89 
     90     def down_event(self, event):
     91         index = self.listbox.index("active")
     92         if self.listbox.selection_includes(index):
     93             index = index + 1
     94         else:
     95             index = 0
     96         if index >= self.listbox.size():
     97             self.listbox.bell()
     98         else:
     99             self.select(index)
    100             self.on_select(index)
    101         return "break"
    102 
    103     def select(self, index):
    104         self.listbox.focus_set()
    105         self.listbox.activate(index)
    106         self.listbox.selection_clear(0, "end")
    107         self.listbox.selection_set(index)
    108         self.listbox.see(index)
    109 
    110     # Methods to override for specific actions
    111 
    112     def fill_menu(self):
    113         pass
    114 
    115     def on_select(self, index):
    116         pass
    117 
    118     def on_double(self, index):
    119         pass
    120 
    121 
    122 def test():
    123     root = Tk()
    124     root.protocol("WM_DELETE_WINDOW", root.destroy)
    125     class MyScrolledList(ScrolledList):
    126         def fill_menu(self): self.menu.add_command(label="pass")
    127         def on_select(self, index): print "select", self.get(index)
    128         def on_double(self, index): print "double", self.get(index)
    129     s = MyScrolledList(root)
    130     for i in range(30):
    131         s.append("item %02d" % i)
    132     return root
    133 
    134 def main():
    135     root = test()
    136     root.mainloop()
    137 
    138 if __name__ == '__main__':
    139     main()
    140