微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么小部件在tkinter画布中彼此堆叠?

如何解决为什么小部件在tkinter画布中彼此堆叠?

我一直在使用tkinter在 python中创建程序,而我的下载选项卡需要滚动条。在进行一些Google搜索后,我发现使整个应用程序可滚动并不是一件容易的事,因为只有两个小部件本身支持滚动条小部件。我搜索了它,发现了一种方法,但是,当我自己尝试实现它时,我遇到了一个错误。当我通过这种方法使用网格时,小部件彼此堆叠,而不是放在单独的行上。我尝试使用本教程的for循环执行相同的操作,问题已解决,但我不希望我的程序使用for循环。这是没有for循环的代码

from tkinter import *
from tkinter import ttk

available_row = 0

root = Tk()
root.title("A Scrollbar")
root.geometry("580x308")
# Create a download frame
download_fr = Frame(root,width=580,height=308)
big_lbl = Label(download_fr,text="Just a BIG label. ",font=("Helvetica","30","bold"))
prg_br = ttk.Progressbar(download_fr,orient=HORIZONTAL,length=300,mode='indeterminate')



def pack_bars():
    global available_row
    big_lbl.pack_forget()
    prg_br.pack_forget()
    # Pack the Scrollbar
    my_scrollbar.pack(side=RIGHT,fill=Y)
    # Configure the canvas
    cnava.configure(yscrollcommand=my_scrollbar.set)
    cnava.bind("<Configure>",lambda e: cnava.configure(scrollregion=cnava.bBox("all")))
    # Create another frame inside the canvas
    second_frame = Frame(cnava)
    # Add that new frame to a window in the canvas
    cnava.create_window((0,0),window=second_frame,anchor="nw")
    ttk.Button(second_frame,text=f"This is the {available_row}th button").grid(row=available_row,column=0)
    available_row += 1
    print(f"Next available row: {available_row}")


btn = Button(download_fr,text="Pack progress bars. ",command=pack_bars)
# Create a canvas
cnava = Canvas(download_fr,bg="red")
# Create a Scrollbar
my_scrollbar = ttk.Scrollbar(download_fr,orient=VERTICAL,command=cnava.yview)
big_lbl.pack(pady=(85,5))
prg_br.pack()
prg_br.start(5)
cnava.pack(side=LEFT,fill=BOTH,expand=1)
btn.pack()
download_fr.pack(fill=BOTH,expand=1)
root.mainloop()

以下是带有for循环的相同代码

from tkinter import *
from tkinter import ttk


root = Tk()
root.title("A Scrollbar")
root.geometry("580x308")
# Create a download frame
download_fr = Frame(root,mode='indeterminate')


def pack_bars():
    big_lbl.pack_forget()
    prg_br.pack_forget()
    # Pack the Scrollbar
    my_scrollbar.pack(side=RIGHT,anchor="nw")
    # Creating a loop to grid 100 buttons
    for i in range(100):
        ttk.Button(second_frame,text=f"This is the {i}th button").grid(row=i,column=0)


btn = Button(download_fr,expand=1)
root.mainloop()

似乎在第一个程序中,画布没有调整大小,因为红色区域没有变化,因此按钮彼此之间呈束带状。我该如何解决这个问题?

解决方法

您创建一个新的second_frame并在执行pack_bars()时将其放在画布中的同一位置。您应该在函数外创建一次second_frame

此外,您应该在<Configure>上绑定second_frame而不是cnava

下面是根据您的代码修改的代码:

from tkinter import *
from tkinter import ttk

available_row = 0

root = Tk()
root.title("A Scrollbar")
root.geometry("580x308")
# Create a download frame
download_fr = Frame(root,width=580,height=308)
big_lbl = Label(download_fr,text="Just a BIG label. ",font=("Helvetica","30","bold"))
prg_br = ttk.Progressbar(download_fr,orient=HORIZONTAL,length=300,mode='indeterminate')



def pack_bars():
    global available_row
    big_lbl.pack_forget()
    prg_br.pack_forget()
    # Pack the Scrollbar
    my_scrollbar.pack(side=RIGHT,fill=Y)
    # add a new button to second_frame
    ttk.Button(second_frame,text=f"This is the {available_row}th button").grid(row=available_row,column=0)
    available_row += 1
    print(f"Next available row: {available_row}")


btn = Button(download_fr,text="Pack progress bars. ",command=pack_bars)
# Create a canvas
cnava = Canvas(download_fr,bg="red")
# Create a Scrollbar
my_scrollbar = ttk.Scrollbar(download_fr,orient=VERTICAL,command=cnava.yview)
cnava.configure(yscrollcommand=my_scrollbar.set)

big_lbl.pack(pady=(85,5))
prg_br.pack()
prg_br.start(5)
cnava.pack(side=LEFT,fill=BOTH,expand=1)
btn.pack()
download_fr.pack(fill=BOTH,expand=1)

# Create another frame inside the canvas
second_frame = Frame(cnava)
# Add that new frame to a window in the canvas
cnava.create_window(0,window=second_frame,anchor='nw')
# update canvas scrollregion whenever the size of second_frame is changed
second_frame.bind('<Configure>',lambda e: cnava.configure(scrollregion=cnava.bbox('all')))

root.mainloop()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。