我使用以下问题的答案制作了一个自定义tkinter小部件(ScrollFrame)以制作可滚动框架:Tkinter scrollbar for frame
一切正常,但每次将新的小部件添加到ScrollFrame中时,我都必须调用“ ConfigureCanvas”函数,以调整滚动区域的大小。当将新的小部件打包/网格化/放置到“滚动框架”中时,是否可以调用任何事件绑定?
例如:
class ScrollFrame(Frame):
'''
'''
self.packFrame.bind('<NewChildWidgetAdded>', self.ConfigureCanvas)
'''
'''
exampleLabel = Label(packFrame, text='Hello')
exampleLabel.pack() # activate the "NewChildWidgetAdded" event?
这是工作代码(python 3+)。我创建了一个循环,该循环创建了50个标签,可以给我一些滚动的内容。
import tkinter
from tkinter import Tk, Frame, filedialog, Button, Listbox, Label, Entry, Text, Canvas, Scrollbar, Radiobutton, Checkbutton, Menu, IntVar, StringVar, BooleanVar, Grid, OptionMenu, Toplevel, ALL, CURRENT, END
#imported more than i needed, copied from other code where this is all used.
class ScrollFrame(Frame):
def __init__(self, frame, *args, **kwargs):
Frame.__init__(self, frame, *args, **kwargs)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.vScroll = Scrollbar(self, orient='vertical')
self.vScroll.grid(row=0, column=1, sticky='wens')
self.hScroll = Scrollbar(self, orient='horizontal')
self.hScroll.grid(row=1, column=0, sticky='wens')
self.canvas = Canvas(self, bd=0, highlightthickness=0, xscrollcommand=self.hScroll.set, yscrollcommand=self.vScroll.set, bg='green')
self.canvas.grid(row=0, column=0, sticky='wens')
self.vScroll.config(command=self.canvas.yview)
self.hScroll.config(command=self.canvas.xview)
self.packFrame = Frame(self.canvas, bg='blue')
self.packWindow = self.canvas.create_window(0,0, window=self.packFrame, anchor='nw')
def ConfigureCanvas(self):
self.packFrame.update_idletasks()
size = (self.packFrame.winfo_reqwidth(), self.packFrame.winfo_reqheight())
self.canvas.config(scrollregion=(0,0,size[0], size[1]))
mw = Tk()
scrollCavnas = ScrollFrame(mw)
scrollCavnas.pack(side='right', fill='both', expand='yes')
scrollFrame = scrollCavnas.packFrame
temp = 0
while temp < 50:
Label(scrollFrame, text=temp).grid(row=temp, column=temp)
temp += 1
scrollCavnas.ConfigureCanvas() # don't want to have to call this every time a new widget is added.
mw.mainloop()
我尝试过:
self.packFrame.bind('<map>', self.ConfigureCanvas)
但是,看起来只有在创建ScrollFrame时才会调用此函数,而不是在向ScrollFrame添加新的子窗口小部件时调用。
我查看了文档(http://tcl.tk/man/tcl8.5/TkCmd/bind.htm#M13),但没有发现任何可以做我想做的事情。
答案 0 :(得分:0)
一种解决方案是使用Configure事件。缺点是每次滚动小部件时都会调用此方法。
self.packFrame.bind('<Configure>', self.ConfigureCanvas)
def ConfigureCanvas(self, event=None):
self.packFrame.update_idletasks()
size = (self.packFrame.winfo_reqwidth(), self.packFrame.winfo_reqheight())
self.canvas.config(scrollregion=(0,0,size[0], size[1]))
我至少能够获得部分功能,仅在添加新小部件时才能运行。这似乎很笨拙,我相信只有水平滚动才能使用(可以修改为垂直滚动或双向滚动)。它将所需的宽度与当前滚动区域的大小进行比较,如果它们不同,它将调整滚动区域的大小。
def ConfigureCanvas(self, event=None):
scrollRegion = self.canvas['scrollregion'].split(' ')
try:
scrollRegion = int(scrollRegion[2])
except IndexError:
scrollRegion = None
if self.packFrame.winfo_reqwidth() != scrollRegion:
self.packFrame.update_idletasks()
size = (self.packFrame.winfo_reqwidth(), self.packFrame.winfo_reqheight())
self.canvas.config(scrollregion=(0,0,size[0], size[1]))