Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change font size without messing with Tkinter button size

I am having trouble changing the font size of a button in Tkinter, when I attempt to do it the button also expands/contracts based on the size of the text. Is there a way I can alter the text size with the button's size anchored in place?

I ran across this while designing a tic-tac-toe application, however to save you the trouble, here is a very minimal example of the problem in practice:

import Tkinter as tk

MyWindow = tk.Tk()
MyWindow.geometry("500x550")


button = tk.Button(MyWindow,text="Hello!",width=17,height=10,font=('Helvetica', '20'))
button.grid(row=1, column=1)

MyWindow.mainloop()

The most important part here is font=('Helvetica', '15') or more specifically, the number 15. If you change that number and run this again, not only will the text be bigger/smaller, but so will the button! How do I get around this?

It's probably a really simple problem. I've just gotten started with Tkinter. Thanks in advance for any help I receive!

like image 550
warspyking Avatar asked Mar 16 '17 16:03

warspyking


1 Answers

Typically, when you give a button a width, that width is measured in characters (ie: width=1 means the width of one average sized character). However, if the button has an image then the width specifies a size in pixels.  

A button can contain both an image and text, so one strategy is to put a 1x1 pixel as an image so that you can specify the button size in pixels. When you do that and you change the font size, the button will not grow since it was given an absolute size.

Here is an example that illustrates the technique. Run the code, then click on "bigger" or "smaller" to see that the text changes size but the button does not.

import Tkinter as tk
import tkFont

def bigger():
    size = font.cget("size")
    font.configure(size=size+2)

def smaller():
    size = font.cget("size")
    size = max(2, size-2)
    font.configure(size=size)

root = tk.Tk()
font = tkFont.Font(family="Helvetica", size=12)

toolbar = tk.Frame(root)
container = tk.Frame(root)

toolbar.pack(side="top", fill="x")
container.pack(side="top", fill="both", expand=True)

bigger = tk.Button(toolbar, text="Bigger", command=bigger)
smaller = tk.Button(toolbar, text="Smaller", command=smaller)

bigger.pack(side="left")
smaller.pack(side="left")

pixel = tk.PhotoImage(width=1, height=1)
for row in range(3):
    container.grid_rowconfigure(row, weight=1)
    for column in range(3):
        container.grid_columnconfigure(column, weight=1)
        button = tk.Button(container, font=font, text="x",
            image=pixel, compound="center", width=20, height=20)
        button.grid(row=row, column=column)

root.mainloop()

All of that being said, there is almost never a time when this is a good idea. If the user wants a larger font, the whole UI should adapt. Tkinter is really good at making that happen, to the point where it all mostly works by default.

like image 52
Bryan Oakley Avatar answered Sep 18 '22 16:09

Bryan Oakley