Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import tkinter as tk # python 3
- from tkinter import font as tkfont # python 3
- class SampleApp(tk.Tk):
- def __init__(self, *args, **kwargs):
- tk.Tk.__init__(self, *args, **kwargs)
- self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
- container = tk.Frame(self)
- container.pack(side="top", fill="both", expand=True)
- container.grid_rowconfigure(0, weight=1)
- container.grid_columnconfigure(0, weight=1)
- scrollable_frame = ScrollableFrame(container, bg="red")
- scrollable_frame.pack(fill="both", expand=True)
- scrollable_frame.grid_rowconfigure(0, weight=1)
- scrollable_frame.grid_columnconfigure(0, weight=1)
- self.frames = {}
- for F in (StartPage, PageOne, PageTwo):
- page_name = F.__name__
- frame = F(parent=scrollable_frame, controller=self)
- self.frames[page_name] = frame
- # put all of the pages in the same location;
- # the one on the top of the stacking order
- # will be the one that is visible.
- frame.grid(row=0, column=0, sticky="nsew")
- frame.grid_rowconfigure(0, weight=1)
- frame.grid_columnconfigure(0, weight=1)
- frame.config(highlightbackground="green", highlightcolor="green", highlightthickness=1)
- self.show_frame("StartPage")
- def show_frame(self, page_name):
- # Show a frame for the given page name
- frame = self.frames[page_name]
- frame.tkraise()
- FIT_WIDTH = "fit_width"
- FIT_HEIGHT = "fit_height"
- class ScrollableFrame(tk.Frame):
- """
- There is no way to scroll <tkinter.Frame> so we are
- going to create a canvas and place the frame there.
- Scrolling the canvas will give the illution of scrolling
- the frame
- Partly taken from:
- https://blog.tecladocode.com/tkinter-scrollable-frames/
- https://stackoverflow.com/a/17457843/11106801
- master_frame---------------------------------------------------------
- | dummy_canvas----------------------------------------- y_scroll-- |
- | | self--------------------------------------------- | | | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | | |
- | | ------------------------------------------------ | | | |
- | ---------------------------------------------------- | | |
- | | | |
- | x_scroll--------------------------------------------- | | |
- | | | | | |
- | ---------------------------------------------------- --------- |
- --------------------------------------------------------------------
- """
- def __init__(self, master=None, scroll_speed=2,
- hscroll=False, vscroll=True, **kwargs):
- assert isinstance(scroll_speed, int), "`scroll_speed` must be an int"
- self.scroll_speed = scroll_speed
- self.master_frame = tk.Frame(master)
- self.dummy_canvas = tk.Canvas(self.master_frame, **kwargs)
- super().__init__(self.dummy_canvas)
- # Create the 2 scrollbars
- if vscroll:
- self.v_scrollbar = tk.Scrollbar(self.master_frame,
- orient="vertical",
- command=self.dummy_canvas.yview)
- self.v_scrollbar.pack(side="right", fill="y")
- self.dummy_canvas.configure(yscrollcommand=self.v_scrollbar.set)
- if hscroll:
- self.h_scrollbar = tk.Scrollbar(self.master_frame,
- orient="horizontal",
- command=self.dummy_canvas.xview)
- self.h_scrollbar.pack(side="bottom", fill="x")
- self.dummy_canvas.configure(xscrollcommand=self.h_scrollbar.set)
- # Bind to the mousewheel scrolling
- self.dummy_canvas.bind_all("<MouseWheel>", self.scrolling_windows,
- add=True)
- self.dummy_canvas.bind_all("<Button-4>", self.scrolling_linux, add=True)
- self.dummy_canvas.bind_all("<Button-5>", self.scrolling_linux, add=True)
- self.bind("<Configure>", self.scrollbar_scrolling, add=True)
- # Place `self` inside `dummy_canvas`
- self.dummy_canvas.create_window((0, 0), window=self, anchor="nw")
- # Place `dummy_canvas` inside `master_frame`
- self.dummy_canvas.pack(side="top", expand=True, fill="both")
- self.pack = self.master_frame.pack
- self.grid = self.master_frame.grid
- self.place = self.master_frame.place
- self.pack_forget = self.master_frame.pack_forget
- self.grid_forget = self.master_frame.grid_forget
- self.place_forget = self.master_frame.place_forget
- def scrolling_windows(self, event):
- assert event.delta != 0, "On Windows, `event.delta` should never be 0"
- y_steps = int(-event.delta / abs(event.delta) * self.scroll_speed)
- self.dummy_canvas.yview_scroll(y_steps, "units")
- def scrolling_linux(self, event):
- y_steps = self.scroll_speed
- if event.num == 4:
- y_steps *= -1
- self.dummy_canvas.yview_scroll(y_steps, "units")
- def scrollbar_scrolling(self, event):
- region = list(self.dummy_canvas.bbox("all"))
- region[2] = max(self.dummy_canvas.winfo_width(), region[2])
- region[3] = max(self.dummy_canvas.winfo_height(), region[3])
- self.dummy_canvas.configure(scrollregion=region)
- def resize(self, fit=None, height=None, width=None):
- if fit == FIT_WIDTH:
- super().update()
- self.dummy_canvas.config(width=super().winfo_width())
- if fit == FIT_HEIGHT:
- super().update()
- self.dummy_canvas.config(height=super().winfo_height())
- if height is not None:
- self.dummy_canvas.config(height=height)
- if width is not None:
- self.dummy_canvas.config(width=width)
- fit = resize
- class StartPage(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- label = tk.Label(self, text="This is the start page", font=controller.title_font)
- label.pack(side="top", fill="x", pady=10)
- button1 = tk.Button(self, text="Go to Page One",
- command=lambda: controller.show_frame("PageOne"))
- button2 = tk.Button(self, text="Go to Page Two",
- command=lambda: controller.show_frame("PageTwo"))
- button1.pack()
- button2.pack()
- class PageOne(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- label = tk.Label(self, text="This is page 1", font=controller.title_font)
- label.pack(side="top", fill="x", pady=10)
- for i in range(0, 99):
- button = tk.Button(self, text="Go to the start page",
- command=lambda: controller.show_frame("StartPage"))
- button.pack()
- class PageTwo(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- label = tk.Label(self, text="This is page 2", font=controller.title_font)
- label.pack(side="top", fill="x", pady=10)
- button = tk.Button(self, text="Go to the start page",
- command=lambda: controller.show_frame("StartPage"))
- button.pack()
- if __name__ == "__main__":
- app = SampleApp()
- app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement