Rand al'Thor
Rand al'Thor

Reputation: 31

Automatically resizing text with window size in tkinter calculator

I have been working on a tkinter calculator in Python 3.8, with basic buttons and an entry field. I want the text in the buttons and entry field to increase (or decrease) size with the window automatically, in proportion with the buttons themselves -- have yet to work on the entry field font sizes -- and, despite trying for a while, have failed. At certain sizes, the font collapses to the minimum size (see code below) or starts phasing rapidly. It also collapses to minimum size when the window is moved.

Calculator original size

Calculator at another size

# Default font size
fontsize = tkFont.Font(size=11)

def font_change(event):
    # Base size
    normal_width = 418
    normal_height = 295

    # Screen
    screen_width = event.width
    screen_height = event.height

    # Get percentage of screen size from Base size
    percentage_width = screen_width / (normal_width / 100)
    percentage_height = screen_height / (normal_height / 100)

    # Make a scaling factor
    scale_factor = ((percentage_width + percentage_height) / 2) / 100

    # Set the fontsize based on scale_factor,
    # if the fontsize is less than minimum_size
    # it is set to the minimum size
    
    # font_size is the variable to store actual size
    minimum_size = 8
    if scale_factor > minimum_size/18:
        font_size = int(18 * scale_factor)
    
    else:
        font_size = minimum_size

    fontsize.configure(size = font_size)

I bind the function to an event:

root.bind("<Configure>", font_change)

Example of a button,

decimal = Button(
    root,
    text=".",
    command=lambda: press("."),
    font = fontsize, 
    height = 2,
    width=7)
decimal.grid(row=6, column=2, sticky=NW + NE + SW + SE)

It would be appreciated if someone can help me out.

Upvotes: 0

Views: 1116

Answers (1)

Tls Chris
Tls Chris

Reputation: 3934

I constructed a test GUI with two Labels. root.bind( "&LT;Configure&GT;", func ) is fired each time root or any of it's children resize. Code below. When the Labels fire the configure event the font is minimised. Which fires the configure event again, even smaller etc.

import tkinter as tk
from tkinter import font


root = tk.Tk()

root.geometry( "200x100" )

fontsize = font.Font( size = 11 )

tk.Label( root, text = 'Test', font = fontsize ).grid( padx = 5, pady = 5 )
tk.Label( root, text = 'Another Test', font = fontsize ).grid( padx = 5, pady = 5 )

def font_change(event):

    print( event.widget, event )  # See what is happening

    # Base size
    normal_width = 200
    normal_height = 100

    # Screen
    screen_width = event.width
    screen_height = event.height
    print( event.widget, event )

    
    # Get percentage of screen size from Base size
    percentage_width = screen_width / (normal_width / 100)
    percentage_height = screen_height / (normal_height / 100)

    minimum_size = 8

    # Make a scaling factor
    scale_factor = ((percentage_width + percentage_height) / 2) / 100

    # Set the fontsize based on scale_factor,
    # if the fontsize is less than minimum_size
    # it is set to the minimum size
    
    # font_size is the variable to store actual size
    
    if scale_factor > minimum_size/18:
        font_size = int(18 * scale_factor)
    
    else:
        font_size = minimum_size

    fontsize.configure( size = font_size )

root.bind( '<Configure>', font_change )

root.mainloop()

One option is to replace the print statement in the above code with

if event.widget != root:
    return None  # Jump out of the function if the widget firing configure isn't root

Another option would be to read the root width and height in the font_change function, not take the width and height from event.

Upvotes: 1

Related Questions