11

My aim is to have a scrollbar that stays at the right-side of a full-screen window, allowing the user to scroll up and down through various different widgets (such as labels & buttons). From other answers I've seen on this site, I've come to the conclusion that a scrollbar has to be assigned to a canvas in order for it to function properly, which I have tried to include in my code but have not had much success with.

The below code shows a simplified version of what I've managed to accomplish so far:

from tkinter import * root = Tk() root.state("zoomed") root.title("Vertical Scrollbar") frame = Frame(root) canvas = Canvas(frame) Label(canvas, text = "Test text 1\nTest text 2\nTest text 3\nTest text 4\nTest text 5\nTest text 6\nTest text 7\nTest text 8\nTest text 9", font = "-size 100").pack() scrollbar = Scrollbar(frame) scrollbar.pack(side = RIGHT, fill = Y) canvas.configure(yscrollcommand = scrollbar.set) canvas.pack() frame.pack() root.mainloop() 

I'm facing two issues when running this code:

One is that the scrollbar is inactive, and doesn't allow for the user to scroll down to view the rest of the text.

The other is that the scrollbar is attached to the right-side of the text, rather than the right-side of the window.

So far, none of the other answers I've found on this site have enabled me to amend my code to support a fully-functioning scrollbar for my program. I'd be very grateful for any help anyone reading this could provide.

5
  • You have to use create_window rather than pack to put the frame in the canvas. See stackoverflow.com/a/3092341/7432 Commented Nov 10, 2016 at 12:29
  • @bryan-oakley Hi Bryan, thanks for the reply. I've tried replacing '.pack()' with '.create_window((4, 4), window = frame, anchor = "nw")' as the link you've provided demonstrated. Unfortunately, this results in my text label disappearing completely, with only a scrollbar being displayed. Also, should I be placing my frame inside a canvas, rather than a canvas inside my frame? Commented Nov 10, 2016 at 13:38
  • the label needs to be inside the frame, the frame needs to be added to the canvas with create_window. Commented Nov 10, 2016 at 13:49
  • @bryan-oakley Ok, I've changed frame.pack() to frame.create_window((4, 4), window = canvas, anchor = "nw") and I've changed canvas.create_window((4, 4), window = frame, anchor = "nw") back to canvas.pack(). This is giving me the following error: AttributeError: 'Frame' object has no attribute 'create_window'. Commented Nov 10, 2016 at 13:54
  • 1
    if you want to scroll frame then put frame inside canvas (canvas.create_window(..., frame)). if you want to scroll label then put label inside canvas (canvas.create_window(..., label)) or label inside frame (Label(frame)) and frame inside canvas (canvas.create_window(..., frame)). See Bryan link how to add frame to canvas (and have frame with scrollbar) and then you can easily add all widgets in this frame. Commented Nov 11, 2016 at 0:03

2 Answers 2

13

See again link: https://stackoverflow.com/a/3092341/7432

It shows how to create scrolled frame - and then you can add all widgets in this frame.

import tkinter as tk def on_configure(event): # update scrollregion after starting 'mainloop' # when all widgets are in canvas canvas.configure(scrollregion=canvas.bbox('all')) root = tk.Tk() # --- create canvas with scrollbar --- canvas = tk.Canvas(root) canvas.pack(side=tk.LEFT) scrollbar = tk.Scrollbar(root, command=canvas.yview) scrollbar.pack(side=tk.LEFT, fill='y') canvas.configure(yscrollcommand = scrollbar.set) # update scrollregion after starting 'mainloop' # when all widgets are in canvas canvas.bind('<Configure>', on_configure) # --- put frame in canvas --- frame = tk.Frame(canvas) canvas.create_window((0,0), window=frame, anchor='nw') # --- add widgets in frame --- l = tk.Label(frame, text="Hello", font="-size 50") l.pack() l = tk.Label(frame, text="World", font="-size 50") l.pack() l = tk.Label(frame, text="Test text 1\nTest text 2\nTest text 3\nTest text 4\nTest text 5\nTest text 6\nTest text 7\nTest text 8\nTest text 9", font="-size 20") l.pack() # --- start program --- root.mainloop() 
Sign up to request clarification or add additional context in comments.

Comments

4

I would recommend using tkScrolledFrame https://pypi.org/project/tkScrolledFrame/ They have a great little example on the website too. So easy to use and works great for me.

Below is a quick example:

 from tkscrolledframe import ScrolledFrame import tkinter as tk # Create a root window root = tk.Tk() frame_top = tk.Frame(root, width=400, height=250) frame_top.pack(side="top", expand=1, fill="both") # Create a ScrolledFrame widget sf = ScrolledFrame(frame_top, width=380, height=240) sf.pack(side="top", expand=1, fill="both") # Bind the arrow keys and scroll wheel sf.bind_arrow_keys(frame_top) sf.bind_scroll_wheel(frame_top) frame = sf.display_widget(tk.Frame) l = tk.Label(frame, text="Test text 1\nTest text 2\nTest text 3\nTest text 4\nTest text 5\nTest text 6\nTest text 7\nTest text 8\nTest text 9", font="-size 20") l.pack() root.mainloop() 

6 Comments

Please explain how the link relates to the question and how it works.
I'll be honest, it's been a very long time since I've looked at this code, but I think what you've found would've been exactly what I was looking for! Hope this answer helps others 🙂
Okay, I added an example :)
Unfortunately it seems to be dead but then again so is Tkinter :P Thanks for the answer! (I made a non-archived version of the repo at github.com/thetechrobo/tkScrolledFrame)
@TheTechRobotheNerd tkinter is dead? Compared to what?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.