-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscroll.py
More file actions
93 lines (73 loc) · 4.99 KB
/
Copy pathscroll.py
File metadata and controls
93 lines (73 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import tkinter as tk
import platform
# ************************
# Scrollable Frame Class
# ************************
class ScrollFrame(tk.Frame):
def __init__(self, parent):
super().__init__(parent) # create a frame (self)
self.canvas = tk.Canvas(self, borderwidth=0, background="#ffffff") #place canvas on self
self.viewPort = tk.Frame(self.canvas, background="#ffffff") #place a frame on the canvas, this frame will hold the child widgets
self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview) #place a scrollbar on self
self.canvas.configure(yscrollcommand=self.vsb.set) #attach scrollbar action to scroll of canvas
self.vsb.pack(side="right", fill="y") #pack scrollbar to right of self
self.canvas.pack(side="left", fill="both", expand=True) #pack canvas to left of self and expand to fil
self.canvas_window = self.canvas.create_window((4,4), window=self.viewPort, anchor="nw", #add view port frame to canvas
tags="self.viewPort")
self.viewPort.bind("<Configure>", self.onFrameConfigure) #bind an event whenever the size of the viewPort frame changes.
self.canvas.bind("<Configure>", self.onCanvasConfigure) #bind an event whenever the size of the canvas frame changes.
self.viewPort.bind('<Enter>', self.onEnter) # bind wheel events when the cursor enters the control
self.viewPort.bind('<Leave>', self.onLeave) # unbind wheel events when the cursorl leaves the control
self.onFrameConfigure(None) #perform an initial stretch on render, otherwise the scroll region has a tiny border until the first resize
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all")) #whenever the size of the frame changes, alter the scroll region respectively.
def onCanvasConfigure(self, event):
'''Reset the canvas window to encompass inner frame when required'''
canvas_width = event.width
self.canvas.itemconfig(self.canvas_window, width = canvas_width) #whenever the size of the canvas changes alter the window region respectively.
def onMouseWheel(self, event): # cross platform scroll wheel event
if platform.system() == 'Windows':
self.canvas.yview_scroll(int(-1* (event.delta/120)), "units")
elif platform.system() == 'Darwin':
self.canvas.yview_scroll(int(-1 * event.delta), "units")
else:
if event.num == 4:
self.canvas.yview_scroll( -1, "units" )
elif event.num == 5:
self.canvas.yview_scroll( 1, "units" )
def onEnter(self, event): # bind wheel events when the cursor enters the control
if platform.system() == 'Linux':
self.canvas.bind_all("<Button-4>", self.onMouseWheel)
self.canvas.bind_all("<Button-5>", self.onMouseWheel)
else:
self.canvas.bind_all("<MouseWheel>", self.onMouseWheel)
def onLeave(self, event): # unbind wheel events when the cursorl leaves the control
if platform.system() == 'Linux':
self.canvas.unbind_all("<Button-4>")
self.canvas.unbind_all("<Button-5>")
else:
self.canvas.unbind_all("<MouseWheel>")
# # ********************************
# # Example usage of the above class
# # ********************************
# class Example(tk.Frame):
# def __init__(self, root):
# tk.Frame.__init__(self, root)
# self.scrollFrame = ScrollFrame(self) # add a new scrollable frame.
# # Now add some controls to the scrollframe.
# # NOTE: the child controls are added to the view port (scrollFrame.viewPort, NOT scrollframe itself)
# for row in range(100):
# a = row
# tk.Label(self.scrollFrame.viewPort, text="%s" % row, width=3, borderwidth="1",
# relief="solid").grid(row=row, column=0)
# t="this is the second column for row %s" %row
# tk.Button(self.scrollFrame.viewPort, text=t, command=lambda x=a: self.printMsg("Hello " + str(x))).grid(row=row, column=1)
# # when packing the scrollframe, we pack scrollFrame itself (NOT the viewPort)
# self.scrollFrame.pack(side="top", fill="both", expand=True)
# def printMsg(self, msg):
# print(msg)
# if __name__ == "__main__":
# root=tk.Tk()
# Example(root).pack(side="top", fill="both", expand=True)
# root.mainloop()