Introduction
Basic Widgets
Toplevel Widgets
Geometry Management
Binding Functions
Working with Images in Tkinter
Tkinter Advance
Applications and Projects
Creating a frame with both horizontal and vertical scrollbars can be useful when you have content that exceeds the viewable area. Let's dive into how you can create a double scrollbar frame using Tkinter:
First, you need to import the necessary modules:
import tkinter as tk from tkinter import ttk
For convenience, let's encapsulate the behavior in a custom widget:
class DoubleScrollbarFrame: def __init__(self, master, **kwargs): # Creating main frame self.frame = ttk.Frame(master, **kwargs) # Creating horizontal and vertical scrollbars self.v_scroll = ttk.Scrollbar(self.frame, orient="vertical") self.h_scroll = ttk.Scrollbar(self.frame, orient="horizontal") # Creating canvas self.canvas = tk.Canvas(self.frame, yscrollcommand=self.v_scroll.set, xscrollcommand=self.h_scroll.set) self.v_scroll.config(command=self.canvas.yview) self.h_scroll.config(command=self.canvas.xview) # Positioning scrollbars and canvas self.v_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.h_scroll.pack(side=tk.BOTTOM, fill=tk.X) self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # Creating an interior frame to hold the actual content self.inner_frame = ttk.Frame(self.canvas) self.canvas.create_window((0,0), window=self.inner_frame, anchor="nw") # Adjusting scrollable region according to inner frame's size self.inner_frame.bind("<Configure>", self.resize) def resize(self, event=None): self.canvas.configure(scrollregion=self.canvas.bbox("all")) def pack(self, **kwargs): self.frame.pack(**kwargs)
Now, let's see how you can use the custom DoubleScrollbarFrame
:
root = tk.Tk() root.geometry("300x300") scroll_frame = DoubleScrollbarFrame(root) scroll_frame.pack(fill=tk.BOTH, expand=True) for i in range(50): ttk.Label(scroll_frame.inner_frame, text=f"Label {i}").grid(row=i, column=0) ttk.Label(scroll_frame.inner_frame, text=f"Value {i}").grid(row=i, column=1) for i in range(50,100): ttk.Label(scroll_frame.inner_frame, text=f"Longer Label {i}").grid(row=i-50, column=i) root.mainloop()
In this example, we've created a GUI window with a frame that has both vertical and horizontal scrollbars. As you add more widgets to the inner_frame
of the DoubleScrollbarFrame
, you'll notice that the scrollbars adjust accordingly.
You can enhance this basic implementation by adding features like mousewheel scrolling, more responsive adjustments, etc. as per your application's needs.
Creating a dual scrollbar frame in Tkinter:
import tkinter as tk class DualScrollbarFrame(tk.Frame): def __init__(self, master=None, **kwargs): super().__init__(master, **kwargs) self.canvas = tk.Canvas(self, borderwidth=0, background="white") self.vertical_scrollbar = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview) self.horizontal_scrollbar = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview) self.canvas.configure(yscrollcommand=self.vertical_scrollbar.set, xscrollcommand=self.horizontal_scrollbar.set) self.vertical_scrollbar.pack(side="right", fill="y") self.horizontal_scrollbar.pack(side="bottom", fill="x") self.canvas.pack(side="left", fill="both", expand=True) self.interior = tk.Frame(self.canvas) self.canvas.create_window((0, 0), window=self.interior, anchor="nw") self.interior.bind("<Configure>", self._configure_interior) self.canvas.bind("<Configure>", self._configure_canvas) def _configure_interior(self, event): size = (self.interior.winfo_reqwidth(), self.interior.winfo_reqheight()) self.canvas.config(scrollregion="0 0 %s %s" % size) if self.interior.winfo_reqwidth() != self.canvas.winfo_width(): self.canvas.config(width=self.interior.winfo_reqwidth()) def _configure_canvas(self, event): if self.interior.winfo_reqwidth() != self.canvas.winfo_width(): self.canvas.itemconfig(self.interior_id, width=event.width) root = tk.Tk() root.title("Dual Scrollbar Frame in Tkinter") dual_scrollbar_frame = DualScrollbarFrame(root, width=300, height=200) dual_scrollbar_frame.pack(padx=10, pady=10, expand=True, fill="both") # Add widgets to the interior of the frame for i in range(30): tk.Label(dual_scrollbar_frame.interior, text=f"Label {i}").pack() root.mainloop()