【发布时间】:2017-04-26 18:44:14
【问题描述】:
我正在尝试在 tkinter 中开发一个可以像普通框架一样使用的可滚动框架。 感谢这个论坛中的许多提示,我开发了一些代码,如果我将滚动框打包在根窗口中,那正是它应该做的。
不幸的是,如果我使用地点或网格,它会失败。
这里是框架的代码
import tkinter as tk
class ScrollFrame(tk.Frame): #this frame will be placed on a canvas that is in a frame that goes on the parent window
class AutoScrollbar(tk.Scrollbar):
def set(self, *args):
if float(args[0])==0 and float(args[1])==1: self.grid_forget()
else:
if self.cget('orient')=="vertical": self.grid(row=0,column=1,sticky="ns")
else: self.grid(row=1,column=0,sticky="ew")
tk.Scrollbar.set(self, *args)
def __init__(self, root,*args,**args2):
self.outer_frame=tk.Frame(root,*args,**args2) #this is the frame that will be packed in th parent window
self.outer_frame.grid_columnconfigure(0, weight=1)
self.outer_frame.grid_rowconfigure(0, weight=2)
self.canvas = tk.Canvas(self.outer_frame, borderwidth=0, background="#ffffff")
tk.Frame.__init__(self, self.canvas,*args,**args2)
self.vscroll = ScrollFrame.AutoScrollbar(self.outer_frame, orient="vertical", command=self.canvas.yview)
self.hscroll = ScrollFrame.AutoScrollbar(self.outer_frame, orient="horizontal", command=self.canvas.xview)
self.canvas.configure(yscrollcommand=self.vscroll.set, xscrollcommand=self.hscroll.set)
self.canvas.create_window((0,0), window=self, anchor="nw")
self.canvas.grid(row=0,column=0,sticky="news")
self.hscroll.grid(row=1,column=0,sticky="ew")
self.vscroll.grid(row=0,column=1,sticky="ns")
self.bind("<Configure>", self.onFrameConfigure)
def onFrameConfigure(self, event): #Adapt the scroll region #does the resizing
self.canvas.config(scrollregion=self.canvas.bbox("all"))
self.canvas.config(width=event.width, height=event.height)
#convenience functions so the ScrollFrame can be treated like a normal frame
def destr_org(self):tk.Frame.destroy(self)
def destroy(self):
self.destroy=self.destr_org
self.outer_frame.destroy()
def pack(self,*args,**arg2):
self.outer_frame.pack(*args,**arg2)
def place(self,*args,**arg2):
self.outer_frame.place(*args,**arg2)
def grid(self,*args,**arg2):
self.outer_frame.grid(*args,**arg2)
def pack_forget(self,*args,**arg2):
self.outer_frame.pack_forget(*args,**arg2)
def place_forget(self,*args,**arg2):
self.outer_frame.place_forget(*args,**arg2)
def grid_forget(self,*args,**arg2):
self.outer_frame.grid_forget(*args,**arg2)
def config(self,*args,**arg2):
self.outer_frame.config(*args,**arg2)
tk.Frame.config(self,*args,**arg2)
def configure(self,*args,**arg2):
self.outer_frame.config(*args,**arg2)
tk.Frame.config(self,*args,**arg2)
这里是我用来测试它的代码。只需取消注释 f.place 和 f.grid 线即可尝试。
win=tk.Tk()
f=ScrollFrame(win)
for n in range(10):
o=tk.Button(f,text="-----------------------"+str(n)+"------------------------")
o.pack()
f.pack(expand=True, fill=tk.BOTH)
#f.place(x=0, y=0)
#f.grid(column=0,row=0)
由于我没有收到任何错误,因此我有些迷路,并且会感谢提示为什么它不起作用。 我知道有些包带有可滚动的框架,但我真的很想得到一个没有额外导入的框架。 它也确实比必要的复杂一点,但那是因为我试图以一种可以像 tk.Frame 一样填充和放置的方式来设计它
非常感谢
【问题讨论】:
-
你永远不会布局 cons_frame。添加
self.termf.pack()。 -
我也做过一次。这是我的版本:gist.github.com/novel-yet-trivial/…
-
哦,谢谢。更正了布局。现在按钮显示,但滚动并没有更好。奇怪的是,即使 cons_frame 没有打包/显示,按钮仍然显示??
-
所以,我用你的代码做了一个快速测试。效果很好,但似乎也有地方问题。
-
好的,termf 的问题是我的错。它按预期工作,所以我从问题中删除了它。
ScrollFrame.place的问题仍然存在。
标签: scroll tkinter scrollbar frame autoscroll