The TkDocs website is a great resource, but it is not complete. The manpage is complete, but of course does not document Python bindings. ” How to get the screen size in Tkinter? ” points out that the window size can be obtained using root.winfo_screenwidth() / root.winfo_screenheight(), but that addresses only the full window, not individual cells within a grid.
Using the TkDocs code as an example, how can I find the height of, e.g., the third row so that I can set a minsize that prevents the buttons from being hidden? Nothing I’ve tried using bbox() or grid_bbox() returns anything other than (0,0,0,0). What is the proper syntax for returning an actual size?
—– Edit —–
The code now shows how bbox() is used within routines called from the event loop, returning correct values.
from tkinter import *
from tkinter import ttk
# bbox() works after window has been rendered
def e_config(event):
w, h = event.width, event.height
print("Resize: content", w, "x", h)
print("content bbox=", content.bbox())
def OK():
print("OK: winfo, bbox:")
print(" root: ", root.winfo_width(), root.winfo_height(), root.bbox())
print(" content: ", content.winfo_width(), content.winfo_height(), content.bbox())
print(" frame: ", frame.winfo_width(), frame.winfo_height(), frame.bbox())
root = Tk()
content = ttk.Frame(root, padding=(5,5,12,12))
content.bind("<Configure>", e_config)
frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100)
namelbl = ttk.Label(content, text="Name")
name = ttk.Entry(content)
onevar = BooleanVar()
twovar = BooleanVar()
onevar.set(True)
twovar.set(False)
one = ttk.Checkbutton(content, text="One", variable=onevar, onvalue=True)
two = ttk.Checkbutton(content, text="Two", variable=twovar, onvalue=True)
ok = ttk.Button(content, text="Okay", command=OK)
cancel = ttk.Button(content, text="Cancel")
content.grid(column=0, row=0, sticky=(E, W)) # Don't resize vertically
frame.grid(column=0, row=0, columnspan=3, rowspan=2)
namelbl.grid(column=3, row=0, columnspan=2)
name.grid(column=3, row=1, columnspan=2)
one.grid(column=0, row=3)
two.grid(column=1, row=3)
ok.grid(column=3, row=3)
cancel.grid(column=4, row=3)
root.configure(bg="#234")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
content.columnconfigure(0, weight=1)
content.columnconfigure(1, weight=1)
content.columnconfigure(2, weight=1)
content.columnconfigure(3, weight=1)
# This doesn't work - screen hasn't been rendered yet
print("pre-init bbox ", content.bbox())
root.mainloop()
The methods
winfo_widthandwinfo_heightwill give you the actual size of a given widget.Note that neither these methods, nor
bbox, will give you anything useful until the widgets are actually rendered to the screen. If you need to use them you will need to make sure the event loop has had a chance to update the display.Also, be aware that the
bboxmethod returns the bounding box of the slave widgets inside the widget, not the bounding of of the widget itself. That is why the results for frame.grid_bbox() return all zeros — it has nothing inside it so the bounding box is 0,0,0,0. You should, however, see numbers forcontent.box()once the display has been rendered. On my box, for instance, I get (0, 0, 352, 125)