Tkinter Scrollbar not working
You must do three things when configuring a scrolling canvas:
- have the canvas notify the scrollbar when it scrolls, by configuring the
yscrollcommand
attribute of the canvas to point to the scrollbar - have the scrollbar control the canvas when it is dragged, by configuring the
command
attribute of the scrollbar - tell the canvas what part of the virtual canvas should be scrollable by configuring the
scrollregion
attribute of the canvas
You are neglecting to do #3. After adding the widgets to master_frame
you should do this:
self.canvas.configure(scrollregion=self.canvas.bbox("all")
The above will tell the canvas and scrollbar that the area of the canvas that is scrollable is the area that encompasses all of the objects on the canvas.
Finally, you need to remove the following line of code, because you are already adding the frame to the canvas with create_window
. Frames added to a canvas with pack
, place
or grid
won't scroll:
# remove this line
self.master_frame.grid()
For a working example of a scrollable frame, see Adding a scrollbar to a group of widgets in Tkinter
Djones4822
Work with Data and statistics to build analytics for whatever role I'm in.
Updated on June 04, 2022Comments
-
Djones4822 almost 2 years
I have a piece of tkinter code running on python 3.4 that is a large frame placed in a canvas with a vertical scrollbar, however the scrollbar is grayed out and doesn't seem to be linked to the size of the frame. The code I'm using is essentially:
class EntryWindow: def __init__(self, master): self.master = master self.master.minsize(750, 800) self.master.maxsize(1000, 800) self.canvas = tk.Canvas(self.master, borderwidth=0, bg='#ffffff') self.vsb = tk.Scrollbar(self.master) self.master_frame = tk.Frame(self.canvas) self.vsb.pack(side="right", fill='y') self.canvas.pack(side='left', fill='both', expand=True) self.canvas.create_window((0,0), window=self.master_frame, anchor='nw', tags='self.master_frame') self.canvas.config(yscrollcommand=self.vsb.set) self.master_frame.grid() ###build widgets and place into master_frame ...
The
master_frame
is filled with about 36 widgets placed using the grid geometry manager and reaches a vertical height of about 2000 pixels, but the scrollbar doesn't work.I saw a post about using ttk scrollbar, but when I imported that I couldn't get it to work. The input statement I used was:
import tkinter as tk import tkinter.ttk as ttk
and then replaced the line
self.vsb = tk.Scrollbar(self.master)
withself.vsb = ttk.Scrollbar(self.master)
but that didn't fix it either. I also tried removing the min/max sizing on master (those aren't the final values, I've been playing with it).Is there something I'm doing wrong? I feel like it might be in the line where I set the canvas.config() but I read the documentation and it seems to be right. Tomorrow I plan on trying to load the frame into the canvas after I've built the frame.
But in the meantime, and in case that doesn't work, any help would be great! Thanks!
-
Parviz Karimli over 7 yearsFirst of all, you shouldn't use both
pack
andgrid
geometry managment methods at the same time. Although it doesn't seem the root of the problem, it normally raises aTclError
. -
Parviz Karimli over 7 yearsSecondly,
frame
widget is used as a container in which other widgets are nested in. So you should have theframe
widget:master_frame
as the parent of yourcanvas
widget. -
Parviz Karimli over 7 yearsThirdly, I also see that you are having some problems with importing and using
tkinter
properly. Just keep in mind that if youfrom tkinter import *
you can't usetk.<widget>
. Otherwise, it will raise aNameError
. -
Parviz Karimli over 7 yearsAnd you also haven't configured the
command
option of yourscrollbar
. -
Parviz Karimli over 7 yearsAdditionally, your
scrollbar
widget also need to have theframe
widget as its parent. -
Russell Smith over 7 years@ParvizKarimli: your comment about master_frame being the parent of the canvas is wrong. It needs to be a child, just as in the question. Also, I see no problem with the imports. Everywhere the OP accesses a Tkinter command, they are prefixing it with
tk.
.
-
-
Djones4822 over 7 yearsI feel like your last bit of code is the most important to me - my master_frame is filled with widgets aligned with the
grid()
method. When I remove that method, the window shrinks a ton and the scrollbar still doesn't work even after configuring the scrollregion after adding all the widgets -
Djones4822 over 7 yearsI ended up resolving it by using the link you gave and adding the onFrameConfigure function and binding it to the frame's <Configure> but I have no idea why it wouldn't work when I just added the scrollregion line at the end after adding the widgets, any idea there?
-
Russell Smith over 7 years@Apc0243: without seeing your code its impossible to know why it didn't work.