<p>如果你不介意一些小把戏,你可以模拟你想要的。不过这有点像黑客</p>
<p>诀窍在于,当您调用<code>tk.Frame.__init__</code>时,需要将画布作为父对象,使<code>self</code>成为内容框架。当然,要做到这一点,您必须首先创建画布,要创建画布,您必须创建外部框架</p>
<p>它看起来像这样:</p>
<pre><code>class scrolledFrame(tk.Frame):
def __init__(self, parent):
self.outer = tk.Frame(parent)
self.canvas = tk.Canvas(self.outer)
self.scroll = tk.Scrollbar(self.outer, command = self.canvas.yview)
tk.Frame.__init__(self, self.canvas)
self.contentWindow = self.canvas.create_window((0,0), window = self, anchor = "nw")
</code></pre>
<p>但是,当您执行上述操作并尝试在<code>scrolledFrame</code>的实例上调用<code>pack</code>、<code>place</code>或<code>grid</code>时,它将执行错误的操作,因为该实例指向内部框架而不是外部框架</p>
<p>这里有一个技巧:解决方案是将调用重定向到<code>pack</code>、<code>place</code>和<code>grid</code>到外部框架</p>
<pre><code>class scrolledFrame(tk.Frame):
def __init__(self, parent):
...
self.pack = self.outer.pack
self.place = self.outer.place
self.grid = self.outer.grid
</code></pre>
<p>有了它,您可以随意使用<code>scrolledFrame</code>,只要在将它添加到布局时使用<code>pack</code>、<code>place</code>或<code>grid</code></p>
<pre><code>exampleFrame = scrolledFrame(root)
exampleFrame.pack(fill="both", expand=True)
for i in range(100):
exampleLabel = tk.Label(exampleFrame, text = f"I'm in the scrolled frame! ({i})")
exampleLabel.pack()
</code></pre>
<hr/>
<p>这是一个完整的工作示例,不过为了简洁起见,我删除了mouseweel代码</p>
<pre><code>import tkinter as tk
class scrolledFrame(tk.Frame):
def __init__(self, parent):
self.outer = tk.Frame(parent)
self.canvas = tk.Canvas(self.outer)
self.scroll = tk.Scrollbar(self.outer, command = self.canvas.yview)
tk.Frame.__init__(self, self.canvas)
self.contentWindow = self.canvas.create_window((0,0), window = self, anchor = "nw")
self.canvas.pack(fill = "both", expand = True, side = "left")
self.scroll.pack(side = "right", fill = "y")
self.canvas.config(yscrollcommand = self.scroll.set)
self.bind("<Configure>", self.resizeCanvas)
self.pack = self.outer.pack
self.place = self.outer.place
self.grid = self.outer.grid
def resizeCanvas(self, event):
self.canvas.config(scrollregion = self.canvas.bbox("all"))
self.canvas.itemconfig(self.contentWindow, width = self.canvas.winfo_width())
root = tk.Tk()
exampleFrame = scrolledFrame(root)
exampleFrame.pack(fill="both", expand=True)
for i in range(100):
exampleLabel = tk.Label(exampleFrame, text = f"I'm in the scrolled frame! ({i})")
exampleLabel.pack(fill="x")
root.mainloop()
</code></pre>