Я использую следующий код для прокручиваемого фрейма. Теперь я хочу, чтобы каждый столбец в сетке заполнял все окно по горизонтали, в том числе при изменении размера окна.
Для этого подхода я всегда использовал frame.grid_columnconfigure (col_num, weight = 1) и добавлял параметр sticky = "ew" в команду .grid (row, col) при размещении элемента.
По какой-то причине (возможно, это связано с окном Canvas), этот подход не работает в следующем коде.
import tkinter as tk
# ************************
# Scrollable Frame Class
# ************************
class ScrollFrame(tk.Frame):
def __init__(self, parent):
super().__init__(parent) # create a frame (self)
# place canvas on self
self.canvas = tk.Canvas(self, borderwidth=0, background="#ffffff")
# place a frame on the canvas, this frame will hold the child widgets
self.viewPort = tk.Frame(self.canvas, background="#ffffff")
# place a scrollbar on self
self.vsb = tk.Scrollbar(self, orient="vertical",
command=self.canvas.yview)
# attach scrollbar action to scroll of canvas
self.canvas.configure(yscrollcommand=self.vsb.set)
# pack scrollbar to right of self
self.vsb.pack(side="right", fill="y")
# pack canvas to left of self and expand to fil
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.create_window((4, 4), window=self.viewPort, anchor="nw", # add view port frame to canvas
tags="self.viewPort")
# bind an event whenever the size of the viewPort frame changes.
self.viewPort.bind("<Configure>", self.onFrameConfigure)
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox(
"all")) # whenever the size of the frame changes, alter the scroll region respectively.
# ********************************
# Example usage of the above class
# ********************************
class Example(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.scrollFrame = ScrollFrame(self) # add a new scrollable frame.
# try to make the columns filling the entire frame
self.scrollFrame.viewPort.grid_columnconfigure(0, weight=1)
self.scrollFrame.viewPort.grid_columnconfigure(1, weight=1)
# Now add some controls to the scrollframe.
# NOTE: the child controls are added to the view port (scrollFrame.viewPort, NOT scrollframe itself)
for row in range(100):
a = row
tk.Label(self.scrollFrame.viewPort, text="%s" % row, width=3, borderwidth="1",
relief="solid").grid(row=row, column=0, sticky="ew")
t = "this is the second column for row %s" % row
tk.Button(self.scrollFrame.viewPort, text=t, command=lambda x=a: self.printMsg(
"Hello " + str(x))).grid(row=row, column=1, sticky="ew")
# when packing the scrollframe, we pack scrollFrame itself (NOT the viewPort)
self.scrollFrame.pack(side="top", fill="both", expand=True)
def printMsg(self, msg):
print(msg)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
Заранее большое спасибо за любые предложения!