如何滚动浏览函数内部定义的 tkinter 小部件?

How to scroll through tkinter widgets that were defined inside of a function?

我用两个框架创建了一个主根。

但是,当我尝试在函数调用中定义新的小部件时,滚动按钮失去了它的功能。仅当我在代码的顶层定义这些小部件时,较小的框架才可滚动。

我使用了一个简单的 for 循环来创建仅用于测试的标签。

谁能告诉我哪里做错了?

from tkinter import *
from tkinter import ttk



#Creating main window
root = Tk()
root.resizable(width=False, height=False)



#Defining Background

toolbar = Frame(root, width=613, height=114)
toolbar.grid(row=0, column=0)

background_frame = Frame(root, width=615, height=560)
background_frame.grid(row=1, column=0)

background = Canvas(background_frame, width=615, height=560)
background.pack(side=LEFT, fill=BOTH, expand=1)

scroll_bar = ttk.Scrollbar(background_frame, orient=VERTICAL, command=background.yview)
scroll_bar.pack(side=RIGHT, fill=Y)

background.configure(yscrollcommand=scroll_bar.set)
background.bind('<Configure>', lambda e:background.configure(scrollregion = background.bbox('all')))

second_frame = Frame(background)
background.create_window(150,100, window=second_frame, anchor='nw')


def confirm1():
    
    
    for x in range(100): 
        Label(second_frame, text = x ).grid(row=x, column=1)




show_labels = Button(toolbar, text= "Show labels", fg="black", command=confirm1)
show_labels.grid(row=0, column=2)

root.mainloop()

每当您向 second_frame 添加小部件时,您都需要更新背景 canvas' scrollregion。这很容易通过绑定到 that 框架的 <Configure> 事件来实现。

这是您的代码的完整版本,添加了几行 (# WHERE INDICATED) 来执行此操作:

from tkinter import *
from tkinter import ttk

#Creating main window
root = Tk()
root.resizable(width=False, height=False)

#Defining Background
toolbar = Frame(root, width=613, height=114)
toolbar.grid(row=0, column=0)

background_frame = Frame(root, width=615, height=560)
background_frame.grid(row=1, column=0)

background = Canvas(background_frame, width=615, height=560)
background.pack(side=LEFT, fill=BOTH, expand=1)

scroll_bar = ttk.Scrollbar(background_frame, orient=VERTICAL, command=background.yview)
scroll_bar.pack(side=RIGHT, fill=Y)

background.configure(yscrollcommand=scroll_bar.set)
# NOT NEEDED
#background.bind('<Configure>',
#                lambda e: background.configure(scrollregion=background.bbox('all')))

second_frame = Frame(background)
background.create_window(150,100, window=second_frame, anchor='nw')

# ADDED
second_frame.bind('<Configure>',
                  lambda e: background.configure(scrollregion=background.bbox('all')))

def confirm1():
    for x in range(100):
        Label(second_frame, text=x).grid(row=x, column=1)

show_labels = Button(toolbar, text="Show labels", fg="black", command=confirm1)
show_labels.grid(row=0, column=2)

root.mainloop()

单击按钮并滚动 canvas 区域后的结果: