Search code examples
pythontkinteralignmentfont-sizettk

How to align text of Tkinter ttk widgets to the top? Resp. how to prevent the text from moving after rescaling?


Everytime I rescale my window, the text starts to "move to the bottom" of the widget. How can I stop this behaviour? Here are 2 screenshots:

This is how it is not supposed to look like: the text moves to the bottom wehn the font becomes smaller

I want the smaller font to be aligned as in this example with the initial font size (12) This is the desired behaviour with smaller font

MWE:

import tkinter as tk 
import tkinter.font as tkFont
from tkinter import ttk


class MWE():
    def __init__(self, window):
        self.master = window
        self.master.geometry('1920x1080')
        self.mainframe = tk.Frame(self.master)
        self.mainframe.pack()
        self.master.bind('<Configure>', self.font_resize) 
        
        self.customFont = tkFont.Font(family="Helevicta", size=12)
        
        self.combobox = ttk.Combobox(self.mainframe, values=('This text vanishes...', 1,2,3),  font=self.customFont)
        self.combobox.current(0)
        
        self.combobox.grid(row=0, column=0)
        
        self.label = ttk.Label(self.mainframe, text='The label text not', font=self.customFont)
        self.label.grid(row=0, column=1)
    def font_resize(self, event):
        if self.mainframe.winfo_height() != event.width or self.mainframe.winfo_width() != event.height:
            calc_size=(self.master.winfo_height()*1e-5*self.master.winfo_width())+1 # some random formula to compute a font size dependent on the window's size
            int_size=int(calc_size)
            self.customFont['size'] = int_size

root=tk.Tk()

Var=MWE(root)
root.mainloop()

(I reposted this question because I forgot to include a MWE originally...)


Solution

  • I don't know why the ttk.Label adjusts automatically whenever the tkFont.Font's size is changed, but the tkk.Combobox doesn't. Fortunately a fairly simple workaround for that anomaly is to update the font option of the combobox manually whenever the font is changed.

    Off-topic: When you bind '<Configure>' events to a root or toplevel window, it's also automatically bound to every widget it contains. This means that your font_resize() (renamed on_resize() below) method is unnecessarily being called multiple times when the window is resized — mostly harmless in this case but still redundant and a waste of processor time. To minimize any potential impact it might be having, I've also modified the beginning of the callback method so it filters-out these extraneous calls and prevents the rest of the method's code from executing.

    import tkinter as tk
    import tkinter.font as tkFont
    from tkinter import ttk
    
    
    class MWE():
        def __init__(self, window):
            self.master = window
            self.master.geometry('1920x1080')
            self.master.bind('<Configure>', self.on_resize)
    
            self.mainframe = tk.Frame(self.master)
            self.mainframe.pack()
    
            self.customFont = tkFont.Font(family="Helevicta", size=12)
            self.combobox = ttk.Combobox(self.mainframe,
                                         values=('This text vanishes...', 1, 2, 3),
                                         font=self.customFont)
            self.combobox.current(0)
            self.combobox.grid(row=0, column=0)
    
            self.label = ttk.Label(self.mainframe, text='The label text not',
                                   font=self.customFont)
            self.label.grid(row=0, column=1)
    
            self.master.mainloop()
    
        def on_resize(self, event):
            if (event.widget == self.master and  # Ignore calls for children. ADDED.
                (self.master.winfo_height() != event.width
                 or self.master.winfo_width() != event.height)
               ):
                # Compute window size dependent font size.
                calc_size = event.height * 1e-5 * event.width + 1
                self.customFont['size'] = int(calc_size)
                self.combobox['font'] = self.customFont  # ADDED.
    
    
    MWE(tk.Tk())