我正在使用以下代码来制作可滚动框架。现在,我希望网格中的每一列都可以水平填充整个窗口,当窗口大小改变时也是如此。
对于这种方法,我一直使用frame.grid_columnconfigure(col_num,weight = 1),并在放置元素时向.grid(row,col)命令添加了sticky =“ ew”参数。
由于某种原因(可能与画布窗口有关),这种方法在以下代码中不起作用。
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()
非常感谢您的任何建议!
答案 0 :(得分:1)
问题不在于您的列是否扩展和收缩,而是它们所在的框架没有增长或缩小的事实。
要解决此问题,您需要绑定到画布的<Configure>
事件。当其更改大小时,您可以强制内部框架与画布的宽度相同。
首先,建立绑定:
self.canvas.bind("<Configure>", self.onCanvasConfigure)
接下来,定义绑定函数以调整内部框架的宽度:
def onCanvasConfigure(self, event):
self.canvas.itemconfigure("self.viewPort", width=event.width)