Tkinter-框架内的标签数更改时,滚动条不会调整大小

问题描述

我正在尝试创建一个GUI,其中左侧是显示员工ID的ListBox(包含在框架f2中),右侧是另一个框架second_frame(包含在内部画布和外部框架f3),以标签的形式显示每个选定雇员的交易详细信息。

每个员工可以进行多个交易。因此,标签数量必须是动态的,即对于listBox中的第一个选定项,可能有两个标签,而对于listBox中的第二个选定项,可能是一百个。对于每个选择,我都调用两个函数来销毁旧标签并创建新标签。虽然代码可以正常工作,但我无法根据所选的listBox条目来调整滚动条的大小。我是Tkinter的新手,请告知。下面是我的代码

还请注意,从任何函数外部调用时,test()函数都会显示滚动条,而从任何函数内部调用时,则不会显示任何内容

# -*- coding: utf-8 -*-
from tkinter import *

'''def test():
    for i in range(0,50):
        for j in range (0,7):
            Label(second_frame,text=f'{i}{j}',width=20).grid(row=i,column=j,pady=5,padx=5)
'''
# --- function ---
def destroy_frame():
    #f1.grid_forget()
    print("destroying frame")
    for label in second_frame.winfo_children():
        label.destroy()

def create_frame(val):
    print("creating new frame")
    for i in range(0,val):
        for j in range (5):
            Label(second_frame,text=f'{i} {j} ',relief=GROOVE,width=10).grid(row=i,padx=5)

def on_selection(event):
    # here you can get selected element
    print('prevIoUs:',listBox.get('active'))
    print(' current:',listBox.get(listBox.curselection()))

    # or using `event`
    print('(event) prevIoUs:',event.widget.get('active'))
    print('(event)  current:',event.widget.get(event.widget.curselection()))

    print (listBox.get(listBox.curselection()))

    if (listBox.get(listBox.curselection()) == "Eid 1"):
        destroy_frame()
        create_frame(100)

    elif (listBox.get(listBox.curselection()) == "Eid 2"):
        destroy_frame()
        create_frame(200)

    print('---')


root = Tk()
root.geometry('800x500')

#Create base Frames
f1 = Frame(width=800,height=50,bg="yellow",colormap="new")
f1.grid(row=0,columnspan=2)
f1.grid_propagate(False)

f2 = Frame(width=200,height=425,bg="light blue",colormap="new")
f2.grid(row=1,column=0)
f2.grid_propagate(False)

f3 = Frame(width=600,bg="light green",colormap="new")
f3.grid(row=1,column=1)
f3.grid_propagate(False)

#Create header Label
l1_f1 = Label(f1,text="Employee Purchase Entries:",bg="yellow")
l1_f1.grid(row=0,column=0)

#Create ListBox
listBox = ListBox(f2,width=40,height=400)
listBox.grid(row=0,column=0)

#Add Scrollbar to ListBox
list_scrollbar = Scrollbar(f2)
list_scrollbar.grid(row=0,column=1,sticky=NSEW)

#Enter ListBox Data
listBox.insert(1,'Eid 1')
listBox.insert(2,'Eid 2')

listBox.bind('<<ListBoxSelect>>',on_selection)

#configure the ListBox and Scrollbar
listBox.config(yscrollcommand  = list_scrollbar.set)
list_scrollbar.config(command = listBox.yview)

#Create a Canvas
my_canvas = Canvas(f3,width=580,bg="light green")
#my_canvas.pack(side=LEFT,fill=BOTH,expand=1)
my_canvas.grid(row=0,column=0)

#Add a Scrollbar to the canvas
my_scrollbar = Scrollbar(f3,orient=VERTICAL,command=my_canvas.yview)
my_scrollbar.grid(row=0,sticky=NSEW)

#configure the canvas
my_canvas.configure(yscrollcommand=my_scrollbar.set)
my_canvas.bind('<Configure>',lambda e : my_canvas.configure(scrollregion = my_canvas.bBox("all")))

#Create another frame inside the canvas
second_frame = Frame(my_canvas)

#Add the new frame to a window in the canvas
my_canvas.create_window((0,0),window=second_frame,anchor="nw")


#test()

root.mainloop()

解决方法

将小部件添加到框架时,画布不会触发configure事件。而是触发了您的帧。

因此您需要输入以下行:

second_frame.bind('<Configure>',lambda e : my_canvas.configure(scrollregion = my_canvas.bbox("all")))

创建second_frame