Welcome, guest | Sign In | My Account | Store | Cart
# Author: Miguel Martinez Lopez
# Uncomment the next line to see my email
# print "Author's email: ", "61706c69636163696f6e616d656469646140676d61696c2e636f6d".decode("hex")

try:
   
import Tkinter as tk
   
import ttk
except ImportError:
   
import tkinter as tk
   
from tkinter import ttk


class MouseWheel(object):
   
def __init__(self, root, factor = 0.5):
       
self.activeArea = None
       
self.factor = factor

       
import platform
        os
= platform.system()

       
if os == "Linux" :
            root
.bind_all('<4>', self.onMouseWheel,  add='+')
            root
.bind_all('<5>', self.onMouseWheel,  add='+')
       
else:
           
# Windows and MacOS
            root
.bind_all("<MouseWheel>", self.onMouseWheel,  add='+')

   
def onMouseWheel(self,event):
       
if self.activeArea:
           
self.activeArea.onMouseWheel(event.delta)

   
def mouseWheel_bind(self, widget):
       
self.activeArea = widget

   
def mouseWheel_unbind(self):
       
self.activeArea = None

   
def add_scrolling(self, scrollingArea, xscrollbar=None, yscrollbar=None):
        scrollingArea
.bind('<Enter>',lambda event: self.mouseWheel_bind(scrollingArea))
        scrollingArea
.bind('<Leave>', lambda event: self.mouseWheel_unbind())

       
if xscrollbar and not hasattr(xscrollbar, 'onMouseWheel'):
            setattr
(xscrollbar, 'onMouseWheel', lambda delta: scrollingArea.xview("scroll",(-1)*int(delta/(120*self.factor)),"units" ) )

       
if yscrollbar and not hasattr(yscrollbar, 'onMouseWheel'):
            setattr
(yscrollbar, 'onMouseWheel', lambda delta: scrollingArea.yview("scroll",(-1)*int(delta/(120*self.factor)),"units" ) )

        active_scrollbar_on_mouse_wheel
= yscrollbar or xscrollbar
       
if active_scrollbar_on_mouse_wheel:
            setattr
(scrollingArea, 'onMouseWheel', active_scrollbar_on_mouse_wheel.onMouseWheel)

       
for scrollbar in (xscrollbar, yscrollbar):
           
if scrollbar:
                scrollbar
.bind('<Enter>', lambda event, scrollbar=scrollbar: self.mouseWheel_bind(scrollbar) )
                scrollbar
.bind('<Leave>', lambda event: self.mouseWheel_unbind())


class simultaneousScrollbar(ttk.Scrollbar):
   
def __init__(self, master, factor = 0.5, **kwargs):
       
self.__scrollableWidgets = []

       
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.")
       
else:
           
self.__orientLabel = 'y'

        kwargs
['command'] = self.onScroll
       
self.factor = factor

        ttk
.Scrollbar.__init__(self, master, **kwargs)



   
def add_ScrollableArea(self, *scrollableWidgets):
       
for widget in scrollableWidgets:
           
self.__scrollableWidgets.append(widget)
            widget
[self.__orientLabel+'scrollcommand']=self.set

   
def onScroll(self, *args):
       
for widget in self.__scrollableWidgets:
            getattr
(widget, self.__orientLabel+'view')(*args)

   
def onMouseWheel(self, delta):
       
for widget in self.__scrollableWidgets:
            getattr
(widget, self.__orientLabel+'view')("scroll",(-1)*int(delta/(120*self.factor)),"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_ScrollableArea(canvas1,canvas2)

   
MouseWheel(root).add_scrolling(canvas1, xscrollbar=scrollbar)
   
MouseWheel(root).add_scrolling(canvas2, xscrollbar=scrollbar)

    root
.mainloop()

if __name__== '__main__':
    test
()

Diff to Previous Revision

--- revision 6 2014-06-22 17:03:02
+++ revision 7 2016-11-20 00:29:52
@@ -1,167 +1,140 @@
-# Version: 0.4
 
# Author: Miguel Martinez Lopez
 
# Uncomment the next line to see my email
 
# print "Author's email: ", "61706c69636163696f6e616d656469646140676d61696c2e636f6d".decode("hex")
 
-
-import Tkinter as tk
-import ttk
-
-import platform
-os = platform.system()
+try:
+   import Tkinter as tk
+   import ttk
+except ImportError:
+   import tkinter as tk
+   from tkinter import ttk
 
 
 
class MouseWheel(object):
-       def __init__(self, root, factor = 2):
-               global os
-              
-               self.activeArea = None
-              
-               if type(factor) == int:
-                       self.factor = factor
-               else:
-                       raise Exception("Factor must be an integer.")
+    def __init__(self, root, factor = 0.5):
+        self.activeArea = None
+        self.factor = factor
 
-               if os == "Linux" :
-                       root.bind_all('<4>', self.onMouseWheel,  add='+')
-                       root.bind_all('<5>', self.onMouseWheel,  add='+')
-               else:
-                       # Windows and MacOS
-                       root.bind_all("<MouseWheel>", self.onMouseWheel,  add='+')
+        import platform
+        os = platform.system()
 
-       def onMouseWheel(self,event):
-               if self.activeArea:
-                       self.activeArea.onMouseWheel(event)
+        if os == "Linux" :
+            root.bind_all('<4>', self.onMouseWheel,  add='+')
+            root.bind_all('<5>', self.onMouseWheel,  add='+')
+        else:
+            # Windows and MacOS
+            root.bind_all("<MouseWheel>", self.onMouseWheel,  add='+')
 
-       def mouseWheel_bind(self, widget):
-               self.activeArea = widget
+    def onMouseWheel(self,event):
+        if self.activeArea:
+            self.activeArea.onMouseWheel(event.delta)
 
-       def mouseWheel_unbind(self):
-               self.activeArea = None
+    def mouseWheel_bind(self, widget):
+        self.activeArea = widget
 
-       @staticmethod
-       def build_function_onMouseWheel(widget, orient, factor = 1):
-               view_command = getattr(widget, orient+'view')
-               if os == 'Linux':
-                       def onMouseWheel(event):
-                               if event.num == 4:
-                                       view_command("scroll",(-1)*factor,"units" )
-                               elif event.num == 5:
-                                       view_command("scroll",factor,"units" )
-                              
-               elif os == 'Windows':
-                       def onMouseWheel(event):                
-                               view_command("scroll",(-1)*int((event.delta/120)*factor),"units" )
-              
-               elif os == 'Darwin':
-                       def onMouseWheel(event):                
-                               view_command("scroll",event.delta,"units" )                    
-              
-               return onMouseWheel
-              
+    def mouseWheel_unbind(self):
+        self.activeArea = None
 
-       def add_scrolling(self, scrollingArea, xscrollbar=None, yscrollbar=None):
-               scrollingArea.bind('<Enter>',lambda event: self.mouseWheel_bind(scrollingArea))
-               scrollingArea.bind('<Leave>', lambda event: self.mouseWheel_unbind())
+    def add_scrolling(self, scrollingArea, xscrollbar=None, yscrollbar=None):
+        scrollingArea.bind('<Enter>',lambda event: self.mouseWheel_bind(scrollingArea))
+        scrollingArea.bind('<Leave>', lambda event: self.mouseWheel_unbind())
 
-               if xscrollbar and not hasattr(xscrollbar, 'onMouseWheel'):
-                               setattr(xscrollbar, 'onMouseWheel', self.build_function_onMouseWheel(scrollingArea,'x', self.factor) )
+        if xscrollbar and not hasattr(xscrollbar, 'onMouseWheel'):
+            setattr(xscrollbar, 'onMouseWheel', lambda delta: scrollingArea.xview("scroll",(-1)*int(delta/(120*self.factor)),"units" ) )
 
-               if yscrollbar and not hasattr(yscrollbar, 'onMouseWheel'):
-                               setattr(yscrollbar, 'onMouseWheel', self.build_function_onMouseWheel(scrollingArea,'y', self.factor) )
+        if yscrollbar and not hasattr(yscrollbar, 'onMouseWheel'):
+            setattr(yscrollbar, 'onMouseWheel', lambda delta: scrollingArea.yview("scroll",(-1)*int(delta/(120*self.factor)),"units" ) )
 
-               active_scrollbar_on_mouse_wheel = yscrollbar or xscrollbar
-               if active_scrollbar_on_mouse_wheel:
-                       setattr(scrollingArea, 'onMouseWheel', active_scrollbar_on_mouse_wheel.onMouseWheel)
+        active_scrollbar_on_mouse_wheel = yscrollbar or xscrollbar
+        if active_scrollbar_on_mouse_wheel:
+            setattr(scrollingArea, 'onMouseWheel', active_scrollbar_on_mouse_wheel.onMouseWheel)
 
-               for scrollbar in (xscrollbar, yscrollbar):
-                       if scrollbar:
-                               scrollbar.bind('<Enter>', lambda event, scrollbar=scrollbar: self.mouseWheel_bind(scrollbar) )
-                               scrollbar.bind('<Leave>', lambda event: self.mouseWheel_unbind())
+        for scrollbar in (xscrollbar, yscrollbar):
+            if scrollbar:
+                scrollbar.bind('<Enter>', lambda event, scrollbar=scrollbar: self.mouseWheel_bind(scrollbar) )
+                scrollbar.bind('<Leave>', lambda event: self.mouseWheel_unbind())
 
 
 
class simultaneousScrollbar(ttk.Scrollbar):
-       def __init__(self, master, factor = 2, **kwargs):
-               self.__scrollableWidgets = []
-               self.__onMouseWheel_callbacks = []
-              
-               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.")
-               else:
-                       self.__orientLabel = 'y'
+    def __init__(self, master, factor = 0.5, **kwargs):
+        self.__scrollableWidgets = []
 
-               kwargs['command'] = self.onScroll
-               self.factor = factor
+        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.")
+        else:
+            self.__orientLabel = 'y'
 
-               ttk.Scrollbar.__init__(self, master, **kwargs)
+        kwargs['command'] = self.onScroll
+        self.factor = factor
+
+        ttk.Scrollbar.__init__(self, master, **kwargs)
 
 
-       def add_ScrollableArea(self, *scrollableWidgets):
-               for widget in scrollableWidgets:
-                       self.__scrollableWidgets.append(widget)
-                       widget[self.__orientLabel+'scrollcommand']=self.set
-                       onMouseWheel_callback = MouseWheel.build_function_onMouseWheel(widget,self.__orientLabel, self.factor )
-                       self.__onMouseWheel_callbacks.append(onMouseWheel_callback)
-
-       def onScroll(self, *args):
-               for widget in self.__scrollableWidgets:
-                       getattr(widget, self.__orientLabeself.__orientLabell+'view')(*args)
 
-       def onMouseWheel(self, event):
-               for callback in self.__onMouseWheel_callbacks:
-                       callback(event)
-                      
+    def add_ScrollableArea(self, *scrollableWidgets):
+        for widget in scrollableWidgets:
+            self.__scrollableWidgets.append(widget)
+            widget[self.__orientLabel+'scrollcommand']=self.set
+
+    def onScroll(self, *args):
+        for widget in self.__scrollableWidgets:
+            getattr(widget, self.__orientLabel+'view')(*args)
+
+    def onMouseWheel(self, delta):
+        for widget in self.__scrollableWidgets:
+            getattr(widget, self.__orientLabel+'view')("scroll",(-1)*int(delta/(120*self.factor)),"units" )
+
 
def test():
-       root = tk.Tk()
+    root = tk.Tk()
 
-       scrollbar = simultaneousScrollbar(root, orient=tk.HORIZONTAL)
-       scrollbar.pack(side=tk.TOP, fill=tk.X)
+    scrollbar = simultaneousScrollbar(root, orient=tk.HORIZONTAL)
+    scrollbar.pack(side=tk.TOP, fill=tk.X)
 
-       emptySpace = tk.Frame(root, height=18)
-       emptySpace.pack()
+    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)
+    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()
+    frame1= tk.Frame(canvas1)
+    frame1.pack()
 
-       for i in range(20):
-               tk.Label(frame1, text="Label "+str(i)).pack(side=tk.LEFT)
+    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.create_window(0, 0, window=frame1, anchor='nw')
 
-       canvas1.update_idletasks()
+    canvas1.update_idletasks()
 
-       canvas1['scrollregion'] = (0,0,frame1.winfo_reqwidth(), frame1.winfo_reqheight())
+    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)
+    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()
+    frame2= tk.Frame(canvas2)
+    frame2.pack()
 
-       for i in range(20):
-               tk.Label(frame2, text="Label "+str(i)).pack(side=tk.LEFT)
+    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.create_window(0, 0, window=frame2, anchor='nw')
 
-       canvas2.update_idletasks()
-       canvas2['scrollregion'] = (0,0,frame2.winfo_reqwidth(), frame2.winfo_reqheight())
+    canvas2.update_idletasks()
+    canvas2['scrollregion'] = (0,0,frame2.winfo_reqwidth(), frame2.winfo_reqheight())
 
-       scrollbar.add_ScrollableArea(canvas1,canvas2)
+    scrollbar.add_ScrollableArea(canvas1,canvas2)
 
-       MouseWheel(root).add_scrolling(canvas1, xscrollbar=scrollbar)
-       MouseWheel(root).add_scrolling(canvas2, xscrollbar=scrollbar)
+    MouseWheel(root).add_scrolling(canvas1, xscrollbar=scrollbar)
+    MouseWheel(root).add_scrolling(canvas2, xscrollbar=scrollbar)
 
-       root.mainloop()
+    root.mainloop()
 
 
if __name__== '__main__':
-       test()
+    test()

History