[Rod Stephens Books]
Index Books Python Examples About Rod Contact
[Mastodon] [Bluesky]
[Build Your Own Ray Tracer With Python]

[Beginning Database Design Solutions, Second Edition]

[Beginning Software Engineering, Second Edition]

[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

Title: Make a scrolled frame in tkinter and Python

[A scrolled frame holding a large label and a picture]

One of many annoying omissions in tkinter is a scrolled window. You can use scrollbars to scroll things like frames or images, but it's a hassle. To make things worse, practically all of the examples I see online use pack so either the vertical or horizontal scrollbar overlaps the other one.

This example uses grid instead of pack. It's based on this Stack Overflow post.

ScrolledFrame

The following code builds the ScrolledFrame widget.

import tkinter as tk class ScrolledFrame(tk.Frame): def __init__(self, frame, *args, **kwargs): tk.Frame.__init__(self, frame, *args, **kwargs) # Make row 0 and column 0 expand. self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) # Scrollbars. self.v_scroll = tk.Scrollbar(self, orient=tk.VERTICAL) self.v_scroll.grid(row=0, column=1, sticky=tk.NSEW) self.h_scroll = tk.Scrollbar(self, orient=tk.HORIZONTAL) self.h_scroll.grid(row=1, column=0, sticky=tk.NSEW) # Canvas. self.canvas = tk.Canvas(self, xscrollcommand=self.h_scroll.set, yscrollcommand=self.v_scroll.set) self.canvas.grid(row=0, column=0, sticky=tk.NSEW) # Configure the canvas. self.v_scroll.config(command=self.canvas.yview) self.h_scroll.config(command=self.canvas.xview) # Frame. self.frame = tk.Frame(self.canvas) self.frame_window = self.canvas.create_window(0, 0, window=self.frame, anchor=tk.NW) def configure_frame(self): self.frame.update_idletasks() width = self.frame.winfo_reqwidth() height = self.frame.winfo_reqheight() self.canvas.config(scrollregion=(0, 0, width, height))

The ScrolledFrame class inherits from Frame. Its constructor creates vertical and horizontal scrollbars and a Canvas widget. It makes a Frame inside the Canvas and makes a window for it. Finally, after arranging and configuring everything, the constructor returns the frame so the calling code can adds widgets to it.

The configure_frame method configures the canvas so it knows how much space its contents use. You should call configure_frame after you add widgets to the frame so it has the right scrolling area.

Main Program

The main program uses the following code snippet to create its ScrolledFrame.

# Make a ScrolledFrame. scrolled_frame = ScrolledFrame(self.window) scrolled_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True) # Save the frame so we can put things in it. my_frame = scrolled_frame.frame ############################### # Put some things in the frame. label = tk.Label(my_frame, text='A pretty long label in a big font', height=5, padx=20, bg='light yellow') label.config(font = ('Arial', 30)) label.grid(row=0, column=0) path = 'robot_working.jpg' image = Image.open(path) self.tk_image = ImageTk.PhotoImage(image) image_label = tk.Label(my_frame, image=self.tk_image) image_label.grid(column=1, row=1) # Configure the frame. (Do this after adding all contained widgets.) scrolled_frame.configure_frame()

This code first creates the ScrolledFrame and packs it to fill the window. It then gets the ScrolledFrame's Frame widget so it can put things inside it.

Next, the program adds a large label with a big font to row 0, column 0. It then adds an image to row 1, column 1.

The snippet finishes by calling the ScrolledFrame's configure_frame method.

Conclusion

That's all there is to it! The ScrolledFrame class takes some thinking, but using it is pretty easy. Just:

  1. Create the ScrolledFrame and pack or grid it as usual.
  2. Get the ScrolledFrame's frame and put widgets inside it.
  3. Call the ScrolledFrame's configure_frame method.

Download the example to see additional details.

© 2024 - 2025 Rocky Mountain Computer Consulting, Inc. All rights reserved.