tkinter 滚动框架按钮随框架调整大小
tkinter Scrolled Frame Buttons Resize with Frame
我(在帮助下)创建了一个带有滚动条的框架 class。似乎效果很好,但我希望按钮能够根据框架的大小自行调整大小。现在,如果您看的话,它们都聚集在左侧。我看过很多例子,这似乎很常见。下面包含一些简单的 运行 代码,因此您可以看到问题。下面附上问题图片。
谢谢。
from tkinter import *
class ScrolledFrame(Frame):
def __init__(self, top, *args, **kwargs):
Frame.__init__(self, top, *args, **kwargs)
hscrollbar = Scrollbar(self, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)
vscrollbar = Scrollbar(self, orient=VERTICAL)
vscrollbar.grid(row=0, column=1, sticky=N+S)
self.canvas = Canvas(self, xscrollcommand=hscrollbar.set, yscrollcommand=vscrollbar.set)
self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
hscrollbar.config(command = self.canvas.xview)
vscrollbar.config(command = self.canvas.yview)
# Make the canvas expandable
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# Create the canvas contents
self.frame = Frame(self.canvas)
self.frame.rowconfigure(1, weight=1)
self.frame.columnconfigure(1, weight=1)
self.canvas.create_window(0, 0, window=self.frame, anchor=N+W)
self.canvas.config(scrollregion=self.canvas.bbox('all'))
self.frame.bind('<Configure>', self.frame_changed)
def frame_changed(self, event):
self.frame.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox('all'))
root = Tk()
frame = ScrolledFrame(root)
frame.grid(row=0, column=0, sticky=N+E+W+S)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
for i in range(20):
button = Button(frame.frame, text='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx %d' % i)
button.pack(fill=BOTH, side=TOP, expand=True)
root.mainloop()
实际上,您的按钮 正在 填充框架。当你给不同的元素背景颜色时,你可以看到这一点。我将你的外框设为红色,canvas 设为绿色,带按钮的框设为蓝色:
您可以看到实际上是内部框架没有填满 canvas,而不是您的按钮没有填满框架。
要使框架填充 canvas,如 的答案中所述,您可以对 canvas <Configure>
事件进行绑定以拉伸如果 canvas 大于按钮的最小尺寸,则将框架设置为 canvas 尺寸。为此,您必须将放置的框架的 ID 保存在 canvas:
self.canvas_frame = self.canvas.create_window(0, 0, window=self.frame, anchor=N+W)
self.canvas.bind('<Configure>', self.canvas_changed)
def canvas_changed(self, event):
if self.frame.winfo_reqwidth() < self.canvas.winfo_width():
self.canvas.itemconfigure(self.canvas_frame, width=self.canvas.winfo_width())
为确保在不需要时没有水平滚动条,您可能需要稍微减小框架的宽度 (width=self.canvas.winfo_width()-4
)。
我(在帮助下)创建了一个带有滚动条的框架 class。似乎效果很好,但我希望按钮能够根据框架的大小自行调整大小。现在,如果您看的话,它们都聚集在左侧。我看过很多例子,这似乎很常见。下面包含一些简单的 运行 代码,因此您可以看到问题。下面附上问题图片。
谢谢。
from tkinter import *
class ScrolledFrame(Frame):
def __init__(self, top, *args, **kwargs):
Frame.__init__(self, top, *args, **kwargs)
hscrollbar = Scrollbar(self, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)
vscrollbar = Scrollbar(self, orient=VERTICAL)
vscrollbar.grid(row=0, column=1, sticky=N+S)
self.canvas = Canvas(self, xscrollcommand=hscrollbar.set, yscrollcommand=vscrollbar.set)
self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
hscrollbar.config(command = self.canvas.xview)
vscrollbar.config(command = self.canvas.yview)
# Make the canvas expandable
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# Create the canvas contents
self.frame = Frame(self.canvas)
self.frame.rowconfigure(1, weight=1)
self.frame.columnconfigure(1, weight=1)
self.canvas.create_window(0, 0, window=self.frame, anchor=N+W)
self.canvas.config(scrollregion=self.canvas.bbox('all'))
self.frame.bind('<Configure>', self.frame_changed)
def frame_changed(self, event):
self.frame.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox('all'))
root = Tk()
frame = ScrolledFrame(root)
frame.grid(row=0, column=0, sticky=N+E+W+S)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
for i in range(20):
button = Button(frame.frame, text='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx %d' % i)
button.pack(fill=BOTH, side=TOP, expand=True)
root.mainloop()
实际上,您的按钮 正在 填充框架。当你给不同的元素背景颜色时,你可以看到这一点。我将你的外框设为红色,canvas 设为绿色,带按钮的框设为蓝色:
您可以看到实际上是内部框架没有填满 canvas,而不是您的按钮没有填满框架。
要使框架填充 canvas,如 <Configure>
事件进行绑定以拉伸如果 canvas 大于按钮的最小尺寸,则将框架设置为 canvas 尺寸。为此,您必须将放置的框架的 ID 保存在 canvas:
self.canvas_frame = self.canvas.create_window(0, 0, window=self.frame, anchor=N+W)
self.canvas.bind('<Configure>', self.canvas_changed)
def canvas_changed(self, event):
if self.frame.winfo_reqwidth() < self.canvas.winfo_width():
self.canvas.itemconfigure(self.canvas_frame, width=self.canvas.winfo_width())
为确保在不需要时没有水平滚动条,您可能需要稍微减小框架的宽度 (width=self.canvas.winfo_width()-4
)。