How do I make the font size change to fit the frame? (Tkinter, Python 3.10)

117 Views Asked by At

I'm trying to make the font size change to make the text fit the frame.

My current code:

import tkinter as tk

root = tk.Tk()

text = tk.Text(root, font="Courier", wrap=None)
text.pack(expand=True, fill="both")
text.insert("end", user_input_text)

root.mainloop()

The display text is based off of user input and can be any length.

2

There are 2 best solutions below

2
On

This method "adjust_font_size" gets called on any keypress within the text widget and adjusts the font size based off the text length. The min and max have been set to 8 and 20 but you can adjust these as needed.

import tkinter as tk

def adjust_font_size(event):
    # Calculate the new font size based on the text length
    text_length = len(text.get("1.0", "end-1c"))

    if text_length ==0:
        return

    new_font_size = max(8, min(20, int(20 / (text_length ** 0.3))))

    # Update the font size
    text.configure(font=("Courier", new_font_size))

root = tk.Tk()
root.geometry("600x400") # Set fixed window size

text = tk.Text(root, font=("Courier", 12), wrap=None)
text.pack(expand=True, fill="both")

# Bind the adjustment function to text modification events
text.bind("<KeyRelease>", adjust_font_size)

root.mainloop()
0
On

It's possible to scale fonts by using metrics and measure from tkinter font.

How It Works:

myfont is defined with fontsize variable.

Font dimensions wide and high are extracted using measure and metrics.

The binding to mytext connects to grower via 'Configure'.

Function grower handles the font change by modifying myfont['size'].

These changes are automatically applied to all text in mytext.

You can experiment by changing fontsize and scalar.

import tkinter as tk
from tkinter import font

fontsize, scalar = 8, 1

app = tk.Tk()
# Enable grid manager to resize Text widget
app.rowconfigure(0, weight = 1)
app.columnconfigure(0, weight = 1)

myfont = font.Font(family = "consolas", size = fontsize)
wide = myfont.measure(0)
high = myfont.metrics("linespace")

mytext = tk.Text(
    app, width = 20, height = 6, font = myfont,
    tabs = 4 * wide, wrap = tk.NONE)
mytext.grid(sticky = tk.NSEW)

def grower(event):
    w, h = event.width, event.height
    try:

        myfont["size"] = int(w / wide / scalar)
        print(myfont.measure(0), myfont.metrics("linespace"))

    except ZeroDivisionError as err:
        print(f"{err}")

app.geometry("390x218")
mytext.bind("<Configure>", grower)

mytext.insert("1.0", f"Wide = {mytext.winfo_width()}\nHigh = {mytext.winfo_height()}\n")
app.mainloop()