# Version: 0.6
# Author: Miguel Martinez Lopez
# Uncomment the next line to see my email
# print("Author's email: ", "61706c69636163696f6e616d656469646140676d61696c2e636f6d".decode("hex"))
try:
from Tkinter import Canvas, Frame
from ttk import Scrollbar, Frame as TFrame
from Tkconstants import HORIZONTAL, VERTICAL, BOTH, N, S, E, W
except ImportError:
from tkinter import Canvas, Frame
from tkinter.ttk import Scrollbar, Frame as TFrame
from tkinter.constants import HORIZONTAL, VERTICAL, BOTH, N, S, E, W
import platform
__all__ = ["Scrolling_Area", "Scrolling_T_Area"]
class Abstract_ScrollingArea(object):
OS = platform.system()
def __init__(self, frame_widget, root, mousewheel_speed, scroll_horizontally, scroll_vertically, kw):
if scroll_horizontally==False and scroll_vertically == False:
raise Exception("No direction for scrolling indicated")
frame_widget.__init__(self, root)
self._active_area = None
if type(mousewheel_speed) == int:
self.mousewheel_speed = mousewheel_speed
else:
raise Exception("mousewheel_speed must be an integer.")
_onMouseWheel = lambda event: self._active_area._onMouseWheel(event) if self._active_area else None
if self.OS == "Linux" :
root.bind_all('<4>', _onMouseWheel, add='+')
root.bind_all('<5>', _onMouseWheel, add='+')
else:
# Windows and MacOS
root.bind_all("<MouseWheel>", _onMouseWheel, add='+')
self._canvas = Canvas(self, highlightthickness=0)
self._canvas.grid(row=0, column=0, sticky="nsew")
self.rowconfigure( 0, weight=1)
self.columnconfigure(0, weight=1)
self.interiorFrame= frame_widget(self._canvas, **kw)
self.interiorFrame.pack()
self._canvas.create_window(0, 0, window=self.interiorFrame, anchor='nw', tags="inner_frame")
self._canvas.bind('<Configure>', self._configure_canvas)
if scroll_vertically:
self.vscrollbar = Scrollbar(self, orient=VERTICAL)
self.vscrollbar._onMouseWheel = self._build_function_onMouseWheel('y')
self.vscrollbar.grid(row=0, column=1,sticky=N+S)
self._canvas.configure(yscrollcommand=self.vscrollbar.set)
self.vscrollbar['command']=self._canvas.yview
else:
self.vscrollbar = None
if scroll_horizontally:
self.hscrollbar = Scrollbar(self, orient=HORIZONTAL)
self.hscrollbar._onMouseWheel = self._build_function_onMouseWheel('x')
self.hscrollbar.grid(row=1, column=0, sticky=E+W)
self._canvas.configure(xscrollcommand=self.hscrollbar.set)
self.hscrollbar['command']=self._canvas.xview
else:
self.hscrollbar = None
self._canvas.bind('<Enter>',lambda event: self._set_active_area(self._canvas))
self._canvas.bind('<Leave>', lambda event: self._unset_active_area())
if self.vscrollbar:
self.main_scrollbar = self.vscrollbar
else:
self.main_scrollbar = self.hscrollbar
self._canvas._onMouseWheel = self.main_scrollbar._onMouseWheel
for scrollbar in (self.hscrollbar, self.vscrollbar):
if scrollbar is not None:
scrollbar.bind('<Enter>', lambda event, scrollbar=scrollbar: self._set_active_area(scrollbar) )
scrollbar.bind('<Leave>', lambda event: self._unset_active_area())
def _configure_canvas(self, event):
width = max(self.interiorFrame.winfo_reqwidth(),self._canvas.winfo_width())
height = max(self.interiorFrame.winfo_reqheight(),self._canvas.winfo_height())
self._canvas.config(scrollregion="0 0 %s %s" % (width, height))
self._canvas.itemconfigure("inner_frame", width=width)
self._canvas.itemconfigure("inner_frame", height=height)
def _set_active_area(self, widget):
self._active_area = widget
def _unset_active_area(self):
self._active_area = None
def _build_function_onMouseWheel(self, orient):
view_command = getattr(self._canvas, orient+'view')
if self.OS == 'Linux':
def onMouseWheel(event):
if event.num == 4:
view_command("scroll",(-1)*self.mousewheel_speed,"units" )
elif event.num == 5:
view_command("scroll",self.mousewheel_speed,"units" )
elif self.OS == 'Windows':
def onMouseWheel(event):
view_command("scroll",(-1)*int((event.delta/120)*self.mousewheel_speed),"units" )
elif self.OS == 'Darwin':
def onMouseWheel(event):
view_command("scroll",event.delta,"units" )
return onMouseWheel
def _initialize():
def _scrolling_area(class_name, frame_widget):
def __init__(self, root, mousewheel_speed = 2, scroll_horizontally=True, scroll_vertically=True, **kw):
Abstract_ScrollingArea.__init__(self, frame_widget, root, mousewheel_speed, scroll_horizontally, scroll_vertically, kw)
globals()[class_name] = type(class_name, (frame_widget, Abstract_ScrollingArea), {"__init__":__init__})
for class_name, frame_widget in [("Scrolling_Area", Frame),("Scrolling_T_Area", TFrame)]:
_scrolling_area(class_name, frame_widget)
_initialize()
del _initialize
if __name__== '__main__':
try:
from Tkinter import Tk, Label
except ImportError:
from tkinter import Tk, Label
root = Tk()
scrolling_area = Scrolling_Area(root)
scrolling_area.pack(expand=1, fill=BOTH)
for i in range(20):
rowFrame = Frame(scrolling_area.interiorFrame)
rowFrame.pack()
for j in range(8):
Label(rowFrame, text="Label %s, %s" % (str(i), str(j))).pack(side="left")
root.mainloop()
Diff to Previous Revision
--- revision 7 2017-03-23 22:58:12
+++ revision 8 2017-04-04 22:55:54
@@ -1,30 +1,31 @@
-# Version: 0.5
+# Version: 0.6
# Author: Miguel Martinez Lopez
# Uncomment the next line to see my email
# print("Author's email: ", "61706c69636163696f6e616d656469646140676d61696c2e636f6d".decode("hex"))
try:
- from Tkinter import Canvas
- from ttk import Scrollbar, Frame
+ from Tkinter import Canvas, Frame
+ from ttk import Scrollbar, Frame as TFrame
from Tkconstants import HORIZONTAL, VERTICAL, BOTH, N, S, E, W
except ImportError:
- from tkinter import Canvas
- from tkinter.ttk import Scrollbar, Frame
+ from tkinter import Canvas, Frame
+ from tkinter.ttk import Scrollbar, Frame as TFrame
from tkinter.constants import HORIZONTAL, VERTICAL, BOTH, N, S, E, W
import platform
+__all__ = ["Scrolling_Area", "Scrolling_T_Area"]
-class ScrollingArea(Frame):
+class Abstract_ScrollingArea(object):
OS = platform.system()
-
- def __init__(self, root, mousewheel_speed = 2, scroll_horizontally=True, scroll_vertically=True, **kw):
+
+ def __init__(self, frame_widget, root, mousewheel_speed, scroll_horizontally, scroll_vertically, kw):
if scroll_horizontally==False and scroll_vertically == False:
raise Exception("No direction for scrolling indicated")
- Frame.__init__(self, root, **kw)
+ frame_widget.__init__(self, root)
self._active_area = None
@@ -48,7 +49,7 @@
self.rowconfigure( 0, weight=1)
self.columnconfigure(0, weight=1)
- self.interiorFrame= Frame(self._canvas, **kw)
+ self.interiorFrame= frame_widget(self._canvas, **kw)
self.interiorFrame.pack()
self._canvas.create_window(0, 0, window=self.interiorFrame, anchor='nw', tags="inner_frame")
@@ -65,7 +66,6 @@
self.vscrollbar['command']=self._canvas.yview
else:
self.vscrollbar = None
-
if scroll_horizontally:
self.hscrollbar = Scrollbar(self, orient=HORIZONTAL)
@@ -129,6 +129,19 @@
return onMouseWheel
+def _initialize():
+ def _scrolling_area(class_name, frame_widget):
+ def __init__(self, root, mousewheel_speed = 2, scroll_horizontally=True, scroll_vertically=True, **kw):
+ Abstract_ScrollingArea.__init__(self, frame_widget, root, mousewheel_speed, scroll_horizontally, scroll_vertically, kw)
+
+ globals()[class_name] = type(class_name, (frame_widget, Abstract_ScrollingArea), {"__init__":__init__})
+
+ for class_name, frame_widget in [("Scrolling_Area", Frame),("Scrolling_T_Area", TFrame)]:
+ _scrolling_area(class_name, frame_widget)
+
+
+_initialize()
+del _initialize
if __name__== '__main__':
try:
@@ -138,7 +151,7 @@
root = Tk()
- scrolling_area = ScrollingArea(root)
+ scrolling_area = Scrolling_Area(root)
scrolling_area.pack(expand=1, fill=BOTH)
for i in range(20):