I need to use a Frame widget to do this; I know I can do it without using the frame and just use a big grid to contain everything (with columnspan for the canvas etc.), but I'd like to put stuff in the frame if possible.
Quick info about my software versions:
=> OS: macOS Catalina 10.15.7
=> IDE: PyCharm CE
=> Python version: 3.12.5
=> tkinter Tcl version: 8.6 (from importing tkinter and using: print(tkinter.TclVersion))
I'm trying to implement the following:
I've tried the following, to no avail:
Like I said above, I can easily do this if I just get rid of the frame and grid everything, as follows:
So given what I'm trying to implement, what did I miss / do wrong, that prevented me from being able to expand the width of the grid so that it basically fills the entirety of the window width?
My code is below.
from tkinter import *
# check to see if we're in macOS
import platform
inMac = False # global flag to check whether we're in macOS
if platform.system() == "Darwin":
inMac = True
print("Using macOS ...")
from tkmacosx import Button
window = Tk()
frame = Frame(window, width=500) # [NO HELP]: Setting frame attribute: width=500.
frame.pack()
#frame.grid(row=0,column=0) # [NO HELP]: Trying to put the frame and canvas in grid.
frame.pack_propagate(0) # [NO HELP]: Using Frame.pack_propagate(0) to stop child widgets
# from affecting the dimensions of the frame widget.
button = Button(frame, text="Button")
button.grid(row=0, column=0, sticky=W) # [NO HELP]: Setting "sticky" attribute.
#button.pack(side=LEFT, fill="x", expand=True) # [NO HELP]: Setting "expand" attribute with Button.pack().
label_1 = Label(frame, text="Whatever #1")
label_1.grid(row=0, column=1)
#label_1.pack(side=LEFT, fill="x", expand=True) # [NO HELP]: Setting "expand" attribute with Label.pack().
label_2 = Label(frame, text="Whatever #2")
label_2.grid(row=0, column=2, sticky=E) # [NO HELP]: Setting "sticky" attribute.
#label_2.pack(side=LEFT, fill="x", expand=True) # [NO HELP]: Setting "expand" attribute with Button.pack().
frame.columnconfigure(0, weight=1) # [NO HELP]: Setting equal weights for each column
frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1)
canvas = Canvas(window, width=500, height=500)
#canvas.grid(row=1, column=0) # [NO HELP]: (As above) Trying to put the frame and canvas in grid.
canvas.pack()
# [NO HELP]: Update window before we display it
#window.update()
window.mainloop()
Thank you.
To achieve what you want, you need to:
fill='x'
to frame.pack(...)
so that the frame will be expanded horizontal to have same width as the canvasuniform=<something>
to .grid(...)
on those button and labels to make the three columns having same width. Columns with same uniform
value will have same width.Below is the modified code:
from tkinter import *
import platform
inMac = False
if platform.system() == "Darwin":
inMac = True
print("Using macOS ...")
from tkmacosx import Button
window = Tk()
frame = Frame(window)
frame.pack(fill='x') # added fill='x'
button = Button(frame, text="Button")
button.grid(row=0, column=0, sticky=EW)
label_1 = Label(frame, text="Whatever #1", bg='yellow')
label_1.grid(row=0, column=1, sticky=EW)
label_2 = Label(frame, text="Whatever #2", bg='cyan')
label_2.grid(row=0, column=2, sticky=EW)
frame.columnconfigure(0, weight=1, uniform='a') # added uniform='a'
frame.columnconfigure(1, weight=1, uniform='a')
frame.columnconfigure(2, weight=1, uniform='a')
canvas = Canvas(window, width=500, height=500, bg='pink')
canvas.pack(fill='both', expand=1)
window.mainloop()
Note that I have added sticky=EW
to .grid(...)
on those button and labels so that those widgets will be expanded to fill the allocated space. Also setting background color on those widgets to show the final effect.
Output:
Note that my platform is Windows, but I think that the result will be the same on MacOS.