When trying to use the ttk.Scrollbar feature, my frame won't expand to fill the canvas even with expand=True. I have found similar issues on other posts however the solutions they used aren't fixing my problem.
Here is a simplified version of my code to show the issue. I essentially want the pink area to fill the entire canvas.
import tkinter as tk
from tkinter import ttk
class MyView(tk.Tk):
def __init__(self):
super().__init__()
self.title("Any help is appreciated :)")
self.geometry("600x300")
self.container = OuterFrame(self)
self.container.pack(expand=1, fill="both")
class OuterFrame(tk.Frame):
def __init__(self, container):
super().__init__(container)
#CONTAINERS
self.canvas = tk.Canvas(self)
self.canvas.pack(side="left", expand=1, fill="both")
self.scrollbar = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.scrollbar.pack(side="right", fill="y")
self.canvas.config(yscrollcommand=self.scrollbar.set)
self.canvas_id = tk.Frame(self.canvas)
self.canvas_id.bind("<Configure>", lambda e: self.canvas.config(scrollregion=self.canvas.bbox("all")))
self.canvas.create_window((0,0), window=self.canvas_id, anchor="nw")
self.container = InnerFrame(self.canvas_id)
self.container.pack(expand=1, fill="both")
class InnerFrame(tk.Frame):
def __init__(self, container):
super().__init__(container)
self.config(bg="pink")
self.titles = ["test1", "test2", "test3", "test4", "test5", "test6"]
self.label = tk.Label(self, text="Objectives")
self.label.pack(pady=5)
self.checkvars = {} #for the ckeckbuttons
self.frames = {}
for title in self.titles:
self.checkvars[title] = tk.IntVar()
self.frames[title] = InnerFrameObjective(self, title, self.checkvars[title])
self.frames[title].pack(expand=1, fill="x", pady=(0,15))
class InnerFrameObjective(tk.Frame):
def __init__(self, container, string, checkvar):
super().__init__(container)
self.configure(pady=4, padx=30, bg="pink")
self.title = string
self.Framelabels = InnerFrameObjectiveLabels(self)
self.Framelabels.pack(side="left", expand=1, fill="both")
self.checkbutton = tk.Checkbutton(self, variable=checkvar, onvalue=1, offvalue=0, bg="blue")
self.checkbutton.pack(side="right", expand=1, fill="both")
class InnerFrameObjectiveLabels(tk.Frame):
def __init__(self, container):
super().__init__(container)
self.parent = container
self.config(bg="blue")
self.title = self.parent.title
self.due_date = None
self.label = tk.Label(self, text=self.title, bg="blue")
self.label.pack()
self.label2 = tk.Label(self, text="Due Date:", bg="blue")
self.label2.pack(anchor="w")
a = MyView()
There are a few things to note here:
The self.canvas_id
will only grow as much as the space needed by its children, unless told not to (with pack_propagate(0)
and need to give in the dimensions)
You are manually setting dimension on the main window, which in turn will make the self.canvas
grow to fill that dimension since you are using pack(side="left", expand=1, fill="both")
on self.canvas
.
my frame won't expand to fill the canvas even with expand=True
Your frame self.container
will not expand the entire size of self.canvas
as it can only grow as much as its parent ( self.canvas_id
), which also does not grow as much as the canvas unless told to do so. Also since self.canvas_id
is a window
inside the canvas, you cannot make it grow with pack
like you expect, you will have to fire up an event each time the canvas changes size and change the frame size to match the size of the canvas.
Now another problem arises when you use pack_propagate(0)
, which makes it a problem to get the height
of self.container
to set for the frame to outgrow the current size of canvas (only then the scrolling will work properly). To tackle this, rather than using pack_propagate(0)
and changing the size of self.canvas_id
directly, we will configure its size on self.canvas
instead.
self.canvas.create_window((0,0), window=self.canvas_id, anchor="nw", tags='window') # Add a tag
self.canvas.bind('<Configure>', lambda e: self.canvas.itemconfig('window', width=e.width)) # Use that tag to identify that window and change the size
The explanation kind of assumes you know nothing, so it goes in some concepts that may seem hard to understand.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.