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