Я действительно понимаю, что мой пример слишком велик. У меня есть обходной путь, который я покажу. Единственное достоинство состоит в том, что он показывает ценность определения класса, облегчая уничтожение и замену прокручиваемого фрейма. Решение состоит в том, чтобы уничтожить весь прокручиваемый фрейм и восстановить его. Я не понимаю, почему: self.content_frame.grid (column = 0, row = 0, sticky = 'nw', ipadx = 5, ipady = 5) в строке 53 не работает, но этот обходной путь позволит мне переместиться вперед. Я прошу прощения, если кто-то потратил время на этот вопрос.
import tkinter as tk
from tkinter import ttk
import os
import inspect
import functools
import sys
class ScrollableFrame:
# https://blog.tecladocode.com/tkinter-scrollable-frame
def __init__(self,container):
self.container = container
self.top_frame = tk.Frame(container,height=2)
self.top_frame.configure(bg='gray15')
# create a frame to hold the Canvas andscrollbars
self.canvas = tk.Canvas(container,borderwidth=5)
self.canvas.configure(bg = 'orange')
self.content_frame = tk.Frame(self.canvas, bg = 'yellow')
#self.content_frame.grid_propagate(True)
# create a vertical scrollbar linked to the canvas
self.scrollbar = ttk.Scrollbar(self.canvas, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.scrollbar.set) # again scrollbar.set is a provided function
self.scrollbar.config(command=self.canvas.yview)
self.xscrollbar = ttk.Scrollbar(self.canvas, orient = 'horizontal', command=self.canvas.xview)
self.canvas.configure(xscrollcommand=self.xscrollbar.set)
self.xscrollbar.config(command=self.canvas.xview)
# before we are done we need to put buttons into ScrollableFame, row 0
# and populate the content_frame with widgets
# after this has been done, the bounding box must be created
container.bind(
"<Configure>",
lambda e: self.canvas.configure(
scrollregion=self.canvas.bbox("all")
)
)
def destroy(self):
self.top_frame.destroy()
self.canvas.destroy()
def finish(self):
self.container.config(bg = 'lightgreen')
self.top_frame.pack(side=tk.TOP,fill=tk.BOTH,expand=False)
#self.content_frame.pack(side=tk.TOP,fill = tk.BOTH,expand=False)
self.content_frame.grid_rowconfigure(0,weight=1)
self.content_frame.grid(column=0,row=0,sticky='nw',ipadx = 5,ipady=5)
self.canvas.create_window((0,0), window=self.content_frame)
self.canvas.pack(side=tk.TOP,fill=tk.BOTH,expand=False,ipady=10)
self.scrollbar.pack(fill='both',side='right',expand='false')
self.xscrollbar.pack(fill='both',side='bottom',expand='false')
self.canvas.update_idletasks()
self.canvas.yview_moveto(0)
self.canvas.xview_moveto(0)
class DisplayKeys(tk.Frame):
def __init__(self,parent,*args,**kwargs) :
tk.Frame.__init__(self,parent,*args,**kwargs)
self.keys_ = [f'display{i}' for i in range(30)]
self.parent = parent
self._showless = False
#self._checkbuttons_initialized = None
self.scrollable_frame = ScrollableFrame(parent)
self._label = tk.Label(self.scrollable_frame.top_frame,
text = "Key List",font = LARGE_FONT)
self._label.grid(column=0,row=0)
self._sequence = [1,2,3,29,5,7,21,15,6]
self._showbutton = tk.Button(self.scrollable_frame.top_frame,
text='Show More',
command=lambda:
self._showbutton_action())
self._showbutton.grid(column=2,row=0,padx=10,sticky=tk.N)
self._update_checkbuttons(self.scrollable_frame.content_frame,self._sequence )
def _update_checkbuttons(self,frame,seq):
#print(*seq)
# self._checkbuttons_initialized = True
self.checkVars = []
self.txtVars = []
searchVar = "Search"
self._checkbuttons = []
for i,place in enumerate(seq) :
bv = tk.BooleanVar()
tvar = tk.StringVar()
dn = self.keys_[place]
ck = tk.Checkbutton(frame,text=dn,variable=bv)
ck.grid(column=0,row=i,sticky='w')
ck.grid_rowconfigure(0,weight = 1)
self._checkbuttons.append(ck)
self.checkVars.append(bv)
txt = tk.Entry(frame,width = 30, textvariable = tvar)
txt.bind('<Return>',self._cmgo)
txt.grid(column = 1,row = i,sticky="nw")
txt.grid_rowconfigure(1,weight=2)
#txt.grid_rowconfigure(0,minsize=400,weight = 1)
#txt.grid_columnconfigure(0,weight=1)
self.txtVars.append(tvar)
self.scrollable_frame.finish()
def _cmgo(self):
pass
def _showbutton_action(self):
if not self._showless :
self._sequence = range(len(self.keys_))
button_text = "Show Less"
#self._showbutton.grid(column=2,row=0,sticky=tk.W)
self._showless = True
else :
button_text = "Show More"
#self._showbutton.grid(column=2,row=0,sticky=tk.W)
self._showless = False
self._sequence = [1,2,3,29,5,7,21,15,6]
self.scrollable_frame.destroy()
self.scrollable_frame = ScrollableFrame(self.parent)
self._label = tk.Label(self.scrollable_frame.top_frame,
text = "Key List",font = LARGE_FONT)
self._label.grid(column=0,row=0)
self._showbutton = tk.Button(self.scrollable_frame.top_frame,
text=button_text,
command=lambda:
self._showbutton_action())
self._showbutton.grid(column=2,row=0,padx=10,sticky=tk.N)
self._update_checkbuttons(self.scrollable_frame.content_frame,self._sequence)
if __name__=="__main__" :
LARGE_FONT= ("Verdana", 12)
DISPLAY_KEYS_GEOMETRY='350x450'
root = tk.Tk()
show = DisplayKeys(root)
show.pack()
root.mainloop()