问题
I am not sure why this will not work. I must be missing something because I can make a single frame expand to fit the canvas but I cannot make a frame inside a frame expand to fit the canvas.
I have been fighting with this for hours and I feel like its something obvious.
I am expecting the label inside of the NoteFrame to expand to fill the frame and that NoteFrame expand to fill the canvas.
Here is the minimum code to reproduce the behavior code:
import tkinter as tk
class NoteFrame(tk.Frame):
def __init__(self, container):
super().__init__(container)
self.config(background='white')
for i in range(20):
tk.Label(self, text='test').grid(row=i, column=0, sticky='nsew')
class GCMain(tk.Tk):
def __init__(self):
super().__init__()
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.main_canvas = tk.Canvas(self, background="bisque")
self.main_canvas.columnconfigure(0, weight=1)
self.main_canvas.rowconfigure(0, weight=1)
self.frame_n_canvas = tk.Frame(self.main_canvas)
self.frame_n_canvas.grid(row=0, column=0, sticky='nsew') # tried with and without this
self.frame_n_canvas.columnconfigure(0, weight=1)
self.main_canvas.config(scrollregion=self.main_canvas.bbox("all"), highlightthickness=0)
scrollbar = tk.Scrollbar(self, orient='vertical')
scrollbar.grid(row=0, column=1, sticky='nsw')
scrollbar.config(command=self.main_canvas.yview)
self.main_canvas.config(yscrollcommand=scrollbar.set)
self.main_canvas.grid(row=0, column=0, sticky='nsew')
self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw')
self.main_canvas.bind("<Configure>", self.update_scrollregion)
nf = NoteFrame(self.frame_n_canvas)
nf.grid(row=0, column=0, sticky='nsew') # tried with and without this
def on_resize(self, event):
w, h = event.width, event.height
self.main_canvas.configure(width=w, height=h)
self.frame_n_canvas(width=w, height=h) # tried with and without this
def update_scrollregion(self, event):
self.main_canvas.configure(scrollregion=self.main_canvas.bbox("all"))
if __name__ == '__main__':
GCMain().mainloop()
回答1:
Comment: Dynamic solution
Allow your
Labelto besticky='ew'use.grid_columnconfigure(0, weight=1).class NoteFrame(tk.Frame): def __init__(self, container): super().__init__(container) self.grid_columnconfigure(0, weight=1)You need the item
iidof theCanvas(..., window=object.
No parameterwidth=200, height=200are needed!self.main_canvas.fram_n_canvas_iid =\ self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw')Bind to
"<Configure>as known.self.main_canvas.bind("<Configure>", self.canvas_configure)Resize
.frame_n_canvaswidth in sync with.main_canvaswidth.def canvas_configure(self, event): canvas = event.widget canvas.itemconfigure(canvas.fram_n_canvas_iid, width=canvas.winfo_width())
Question: Frame in canvas will not expand to fit canvas
A widget, here your Frame self.frame_n_canvas, looses the ability to expand, if placed with .create_window(... in a Canvas.
This, .grid(..., is useless, as you later place the same Frame with .create_window(...:
self.frame_n_canvas.grid(row=0, column=0, sticky='nsew') # tried with and without this
...
self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw')
To give your NoteFrame place to expand, use parameter width=200, height=200.
self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw',
width=200, height=200)
To allow your Label to be sticky='ew', you have to do .grid_columnconfigure(...:
class NoteFrame(tk.Frame):
def __init__(self, container):
super().__init__(container)
self.grid_columnconfigure(0, weight=1)
Result:
来源:https://stackoverflow.com/questions/54794843/frame-in-canvas-will-not-expand-to-fit-canvas