How to change tkinter geometry values in regard to (for example) a scrolled text height?

Question:

I was wondering how do the geometry() function values in tkinter come to play with the height value of for example a scrolled text? How can I convert the units to work with each other?

For example: If I want to open a scrolled text box underneath my tkinter window with a click of a button, I know I need then to change my window’s geometry() (height) value, but I don’t know by how much exactly.

(In the following example I randomly added 100 to the geometry value in the function open. But I want a more specific value that translates to the 7 of the height value of the scrolled text)

from tkinter import *
from tkinter import scrolledtext

def open():
    root.geometry(f'{frame_width}x{frame_height+100}')
    st.pack(side="bottom")

frame_width = 900
frame_height = 500

root = Tk()
root.geometry(f'{frame_width}x{frame_height}')
root.configure(bg='white')
root.resizable(False, False)

open_st = Button(root, text="OPEN SCROLLED TEXT", command= open)
open_st.pack()

st = scrolledtext.ScrolledText(root, width=frame_width, height=7)

root.mainloop()
Asked By: queuetzi

||

Answers:

Widgets that contains text usually provide their width and height in character space. This means tkinter takes the average width and height of your font and multiplies it with the given number in width and height.

There are mainly two ways to deal with that, either tk.Font.measure or metrics, if you want to convert characters to pixel or the much more comfortable way by just asking the widget for it’s size via winfo. Happily your case fits for the latter.

The alternate code would looks like this:

def open_text():
    st.pack(side="bottom")
    width, window_height = root.winfo_width(), root.winfo_height()
    requested_text_height = st.winfo_reqheight()
    new_height = window_height + requested_text_height
    root.geometry(f'{width}x{new_height}')

Please note that I have named your function differently. Cause you redefined open in the global namespace of your module and this could lead to unintended behavior. In addition I wonder why you want to do it like this and not just let the geometry managers do their job?

Answered By: Thingamabobs