import Tkinter as tk
class simultaneousScrollbar(tk.Scrollbar):
def __init__(self, master, **kwargs):
self.__scrollableWidgets = []
self.orientLabel = 'y'
if 'orient' in kwargs:
if kwargs['orient']== tk.VERTICAL:
self.orientLabel = 'y'
elif kwargs['orient']== tk.HORIZONTAL:
self.orientLabel = 'x'
else:
raise Exception("Bad 'orient' argument in scrollbar.")
kwargs['command'] = self.onScroll
tk.Scrollbar.__init__(self, master, **kwargs)
self.scrollbarClicked = False
self.mouseOver = False
self.bind_all("<1>", self.onClickOnWindow)
self.bind_all("<MouseWheel>", self.onMouseWheel)
self.bind("<4>", self.onMouseWheel)
self.bind("<5>", self.onMouseWheel)
self.bind("<Enter>", self.onMouseOver)
self.bind("<Leave>", self.onMouseOut)
def add_ScrollableZones(self, *scrollableWidgets):
for widget in scrollableWidgets:
self.__scrollableWidgets.append(widget)
widget[self.orientLabel+'scrollcommand']=self.set
widget.bind("<MouseWheel>", self.onMouseWheel)
def onScroll(self, *args):
for widget in self.__scrollableWidgets:
getattr(widget, self.orientLabel+'view')(*args)
def onClickOnWindow(self,event):
if self.winfo_containing(event.x_root, event.y_root) == self:
self.scrollbarClicked = True
else:
self.scrollbarClicked = False
def onMouseOver(self,event):
self.mouseOver = True
def onMouseOut(self,event):
self.mouseOver = False
def onMouseWheel(self, event):
if self.scrollbarClicked:
mouseWheel = True
else:
if self.mouseOver:
mouseWheel = True
else:
mouseWheel = False
if mouseWheel:
for widget in self.__scrollableWidgets:
getattr(widget, self.orientLabel+'view')("scroll", (-1)*event.delta/120,"units")
def test():
root = tk.Tk()
scrollbar = simultaneousScrollbar(root, orient=tk.HORIZONTAL)
scrollbar.pack(side=tk.TOP, fill=tk.X)
emptySpace = tk.Frame(root, height=18)
emptySpace.pack()
tk.Label(root, text='First scrolled frame:').pack(anchor=tk.W)
canvas1 = tk.Canvas(root, width=300, height=100)
canvas1.pack(anchor=tk.NW)
frame1= tk.Frame(canvas1)
frame1.pack()
for i in range(20):
tk.Label(frame1, text="Label "+str(i)).pack(side=tk.LEFT)
canvas1.create_window(0, 0, window=frame1, anchor='nw')
canvas1.update_idletasks()
canvas1['scrollregion'] = (0,0,frame1.winfo_reqwidth(), frame1.winfo_reqheight())
tk.Label(root, text='Second scrolled frame:').pack(anchor=tk.W)
canvas2 = tk.Canvas(root,width=300, height=100)
canvas2.pack(anchor=tk.NW)
frame2= tk.Frame(canvas2)
frame2.pack()
for i in range(20):
tk.Label(frame2, text="Label "+str(i)).pack(side=tk.LEFT)
canvas2.create_window(0, 0, window=frame2, anchor='nw')
canvas2.update_idletasks()
canvas2['scrollregion'] = (0,0,frame2.winfo_reqwidth(), frame2.winfo_reqheight())
scrollbar.add_ScrollableZones(canvas1,canvas2)
root.mainloop()
if __name__== '__main__':
test()
Diff to Previous Revision
--- revision 1 2014-05-08 02:55:01
+++ revision 2 2014-05-08 03:00:51
@@ -14,7 +14,7 @@
else:
raise Exception("Bad 'orient' argument in scrollbar.")
- kwargs['command'] = command=self.onScroll
+ kwargs['command'] = self.onScroll
tk.Scrollbar.__init__(self, master, **kwargs)