Reputation: 31
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.
# 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
Reputation: 3934
I constructed a test GUI with two Labels. root.bind( "<Configure>", 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