基于此处的示例:Scrollbar in Tkinter grid
我做了一个简化版本,或多或少是我需要的,除了我希望列总是填充框架的宽度,因为窗口正在调整大小。
没有滚动条就非常容易,我只是添加了grid_columnconfigure
并且开箱即用,但是当我添加滚动条时,我无法弄清楚如何让列再次调整大小。
以下是示例:
import tkinter as tk
row = 1
class ProgramWindow(tk.Frame):
def __init__(self):
self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
tk.Frame.__init__(self, self.canvas)
self.grid(column=0, row=0, sticky='ESW')
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
self.grid_columnconfigure(2, weight=1)
tk.Label(self, text="FirstCol", ).grid(row=0, column=0)
tk.Label(self, text="SecndCol", ).grid(row=0, column=1)
tk.Label(self, text="ThirdCol", ).grid(row=0, column=3)
self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side="right", fill="y")
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.create_window((4, 4), window=self)
self.bind("<Configure>", self.OnFrameConfigure)
def OnFrameConfigure(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def addrow(self, stuff, otherstuff):
global row
var = tk.StringVar(value=stuff)
entry = tk.Entry(self, textvariable=var)
entry.grid(row=row, column=0)
var = tk.StringVar(value=otherstuff)
entry = tk.Entry(self, textvariable=var)
entry.grid(row=row, column=1)
var = tk.StringVar(value="foobar")
entry = tk.Entry(self, textvariable=var)
entry.grid(row=row, column=3)
row += 1
def SomeProg():
for i in range(20):
stuff = "Stuff is " + str(i)
otherstuff = i * 4
win.addrow(stuff, otherstuff)
root = tk.Tk()
root.title("Stuff")
win = ProgramWindow()
SomeProg()
root.mainloop()
答案 0 :(得分:2)
我改编了Bryan Oakley对Adding a scrollbar to a group of widgets in Tkinter的回答,以便画布中包含的框架适合画布的宽度。
Canvas窗口对象有一个width选项。因此,每次调整画布大小时,我都会使用
将新画布宽度传递给此宽度选项 self.canvas.itemconfigure(<frame tag>, width=self.canvas.winfo_width())
这是完整的代码
import tkinter as tk
class Example(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
self.frame = tk.Frame(self.canvas, background="#ffffff")
self.frame.columnconfigure(0, weight=1)
self.frame.columnconfigure(1, weight=1)
self.frame.columnconfigure(2, weight=1)
self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side="right", fill="y")
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.create_window((4,4), window=self.frame, anchor="nw",
tags="self.frame")
self.canvas.bind("<Configure>", self.onCanvasConfigure)
self.populate()
def populate(self):
'''Put in some fake data'''
for i in range(100):
tk.Entry(self.frame).grid(row=i, column=0, sticky='ew')
tk.Entry(self.frame).grid(row=i, column=1, sticky='ew')
tk.Entry(self.frame).grid(row=i, column=2, sticky='ew')
def onCanvasConfigure(self, event):
self.canvas.itemconfigure("self.frame", width=self.canvas.winfo_width())
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
if __name__ == "__main__":
root=tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()