Home > other >  How to span a Tkinter frame inside of a Tkinter Canvas
How to span a Tkinter frame inside of a Tkinter Canvas

Time:09-08

I have just started using Tkinter and I have a frame insdie of a canvas placed using the create_window funcion so that I may have a working scrollbar for my program. The issue is the Text widgets that I place in the frame inside of the canvas is not spanning horizontally inside the canvas and I have no idea how to make this happen. I have tried using pack() or grid() and grid_rowconfigure, but if I don't use create_window then the bar on my scroll bar disappears. I can't seem to find any post that addresses this issue, but I may be wrong. Here is the snippet of my code that deals with the GUI of this window:

root = Tk()
# create top part
top=Frame(root)
# create a canvas to scroll
holder = Canvas(top)
# create scroll bar
scroll = Scrollbar(top, orient=VERTICAL, command=holder.yview)
# configure scrollbar for canvas
holder.configure(yscrollcommand=scroll.set)
holder.bind('<Configure>', lambda e: holder.configure(scrollregion=holder.bbox("all")))
# create frame for content inside canvas and add it to the canvas
content = Frame(holder, relief=RAISED)
holder.create_window((0,0), window=content, anchor='nw')
# create bottom part
bottom = Frame(root, relief=SUNKEN)

root.rowconfigure(0, weight=18)
root.rowconfigure(1, weight=1, minsize=50)
root.columnconfigure(0, weight=1)
holder.pack(side=LEFT, fill=BOTH, expand=1)
scroll.pack(side=RIGHT, fill=Y)
top.grid(row=0, column=0, sticky='NSEW')
bottom.grid(row=1, column=0, sticky='NSEW')

num=0
for site in sites:
    temp=Text(content, height = 5)
    temp.configure(state= DISABLED)
    temp.pack(fill=X, side=TOP, padx= 5, pady= 5)
    siteBoxes.append(temp)
    num  = 1

root.mainloop()

CodePudding user response:

First, you should update scrollregion of holder whenever the internal frame content (not the canvas holder) is resized.

Second, you can update the width of the internal frame content whenever the canvas holder is resized.

Below is the updated code:

root = Tk()
# create top part
top=Frame(root)
# create a canvas to scroll
holder = Canvas(top)
# create scroll bar
scroll = Scrollbar(top, orient=VERTICAL, command=holder.yview)
# configure scrollbar for canvas
holder.configure(yscrollcommand=scroll.set)
### --- expand the width of the internal frame to the width of canvas
holder.bind('<Configure>', lambda e: holder.itemconfigure(internal, width=e.width))
# create frame for content inside canvas and add it to the canvas
content = Frame(holder, relief=RAISED)
### --- update scrollregion whenever the internal frame is resized
content.bind('<Configure>', lambda e: holder.configure(scrollregion=holder.bbox("all")))
### --- save the item ID of the internal frame
internal = holder.create_window((0,0), window=content, anchor='nw')
# create bottom part
bottom = Frame(root, relief=SUNKEN)

root.rowconfigure(0, weight=18)
root.rowconfigure(1, weight=1, minsize=50)
root.columnconfigure(0, weight=1)
holder.pack(side=LEFT, fill=BOTH, expand=1)
scroll.pack(side=RIGHT, fill=Y)
top.grid(row=0, column=0, sticky='NSEW')
bottom.grid(row=1, column=0, sticky='NSEW')

num=0
for site in sites:
    temp=Text(content, height = 5)
    temp.configure(state= DISABLED)
    temp.pack(fill=X, side=TOP, padx= 5, pady= 5)
    siteBoxes.append(temp)
    num  = 1

root.mainloop()
  • Related