Skip to content Skip to sidebar Skip to footer

Making Toplevel Resize Itself To Fit The Title

Consider: #!/usr/bin/python from Tkinter import * root=Tk() root.withdraw() top=Toplevel() top.title('Some long title') label = Label(top, text ='short', font=('Times', 18)) lab

Solution 1:

You can't do what you want. Tkinter has no access to information about the titlebar.

Solution 2:

After some digging and testing I think I found something you can use. We need to use the import for tkFont and use actual() to get the font information.

Try the following:

from tkinter import *
import tkinter.font as tkFont

# imports for python 2# from Tkinter import *# import tkFont

root=Tk()
root.withdraw()

top=Toplevel()

label_not_settings = Label(top, text ="Some long title")
label_not_settings.grid(row = 0, column = 0, sticky = 'w')

label_arial_12 = Label(top, text ="Some long title", font = ('Arial', 12))
label_arial_12.grid(row = 1, column = 0, sticky = 'w')

label = Label(top, text ="Some long title", font=('Times', 18))
label.grid(row = 2, column = 0, sticky = 'w')


empty_font = tkFont.Font()
label_not_settings_font = tkFont.Font(font = label_not_settings['font'])
label_arial_12_font = tkFont.Font(font = label_arial_12['font'])
toplevel_font = tkFont.Font(top.title("Some long title")) # no error comes from this line thought I don't think its actually working as intended.
label_font = tkFont.Font(font = label['font'])

print('# Results of priting with .actual() "empty_font = tkFont.Font()"')
print(empty_font.actual())
print("")
print("# Results of priting with .actual() on {}".format("label_not_settings_font"))
print(label_not_settings_font.actual())
print("")
print("# Results of priting with .actual() on {}".format("label_arial_12_font"))
print(label_arial_12_font.actual())
print("")
print("# Results of priting with .actual() on {}".format("toplevel_font"))
print(toplevel_font.actual())
print("")
print("# Results of priting with .actual() on {}".format("label_font"))
print (label_font.actual())

root.mainloop()

for me this resulted in:

# Results of priting with .actual() "empty_font = tkFont.Font()"
{'family': 'Arial', 'size': 12, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}

# Results of priting with .actual() on label_not_settings_font
{'family': 'Segoe UI', 'size': 9, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}

# Results of priting with .actual() on label_arial_12_font
{'family': 'Arial', 'size': 12, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}

# Results of priting with .actual() on toplevel_font
{'family': 'Arial', 'size': 12, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}

# Results of priting with .actual() on label_font
{'family': 'Times New Roman', 'size': 18, 'weight': 'normal', 'slant': 'roman', 'underline': 0, 'overstrike': 0}

It does appear to produce the font information you need. Though I am not 100% sure it is working as intended when calling toplevel_font.actual() it produces the same result as calling on an empty variable (I imaging its just stating the default font but I am not sure). Also if I create a label with text but no font configs then it produces a different font.actual() result.

Update:

Also I have looked into the issue of creating your own title bar with the functionality of the title bar. The issues I have run into so far is the window moves over so the top left corner of the title bar is at the mouse point when dragging the window around, the loss of auto resize function when dragging the window to a side of the monitor and not being able to manually resize the window.

I would imaging it is possible to build a fully functional title bar and I will work on it as I am interested to see if I can make one. But for now here is some information to illustrate the basics of creating ones own title bar.

This bit of code comes from this post: Can I change the title bar in Tkinter?

I have made some small changes but it is basically the same.

from tkinter import *

root = Tk()

defmove_window(event):
    root.geometry('+{0}+{1}'.format(event.x_root, event.y_root))

root.overrideredirect(True) # turns off title bar, geometry
root.geometry('200x100') # set new geometry# make a frame for the title bar
title_bar = Frame(root, bg = 'white', relief = FLAT, bd = 2)

# put a close button on the title bar
close_button = Button(title_bar, text = 'X', relief = FLAT, command = root.destroy)

# a canvas for the main area of the window
window = Canvas(root, bg='black')

# pack the widgets
title_bar.pack(expand = 1, fill = X)
close_button.pack(side = RIGHT)
window.pack(expand = 1, fill = BOTH)
# bind title bar motion to the move window function
title_bar.bind('<B1-Motion>', move_window)

root.mainloop()

Edit:

All this being said I would probably just test on each of the major operating systems and deiced on a good root.geometry() or root.minsize() that will show the text in full of the title. This might not be an elegant solution like using code to calculate text size and applying that size to the windows opening size but it should do the trick.

Post a Comment for "Making Toplevel Resize Itself To Fit The Title"