简体   繁体   中英

Changing the size of a scrollbar in tkinter(using grid layout)

I'm making a Tkinter GUI that allows you to query a database and will display results in a scrollable frame. However, when you produce the results the scrollbar will not adjust to match the new size of the frame. How can I get the scrollbar to be able to display all of the results? I've put together a quick and dirty version of the code to demonstrate the problem I'm having.

import tkinter as tk

def Lookup():
    list = frame_buttons.grid_slaves()
    for l in list:
        l.destroy()
    for x in range(1000):
        tk.Label(frame_buttons, text="test", background="white").grid(row=x)


root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)

frame_main = tk.Frame(root, bg="white")
frame_main.grid(row = 0,sticky='news')
frame_input = tk.Frame(frame_main, background = "white")
frame_input.grid(row=0, column=0, pady=(5, 0), sticky='nw')

tk.Button(frame_input, text="Search", fg="black", background = "grey",command=Lookup).grid(row=3, column=0,sticky='nw')

# Create a frame for the canvas with non-zero row&column weights
frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(row=1, column=0, pady=(5, 0), sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow 5-by-5 buttons resizing later
frame_canvas.grid_propagate(False)

# Add a canvas in that frame
canvas = tk.Canvas(frame_canvas, bg="gray")
canvas.grid(row=0, column=0, sticky="news")

# Link a scrollbar to the canvas
vsb = tk.Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)
frame_buttons = tk.Frame(canvas, bg="gray")
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
for x in range(15):
    tk.Label(frame_buttons, text="blah", background = "white").grid(row=x)
frame_buttons.update_idletasks()
frame_canvas.config(width=500, height=100)
canvas.config(scrollregion=canvas.bbox("all"))
root.mainloop()

this initially puts 20 labels in the scroll region, which is enough to activate the scrollbar. Then when you click search it replaces those 20 lables with 1000 test labels. But only the first 20 will be viewable.

You need to reset the scrollregion whenever the frame changes size and the items are redrawn.

The normal way to do that is to bind to the <Configure> event of the frame so that it happens automatically as the frame grows and shrinks.

Example:

def reset_scrollregion(event):
    canvas.config(scrollregion=canvas.bbox("all"))
...
frame_buttons.bind("<Configure>", reset_scrollregion)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM