Displaying square Tkinter.Button's?
Asked Answered
I

3

5

Why does this code display buttons taller than they are wide?

import Tkinter, tkFont
top = Tkinter.Tk()
right = Tkinter.Frame(top)
right.pack(side = "right")
font = tkFont.Font(family="Helvetica", size=60, weight = tkFont.BOLD)

for i in xrange(6):
    b = Tkinter.Button(right, text = str(i), font = font, width = 1, height = 1)
    top.rowconfigure(i, weight = 1)
    top.columnconfigure(i, weight = 1)
    b.grid(row = i/3, column = i%3, sticky = "NWSE")

top.mainloop()
  • All the buttons are created with width=1, height=1
  • For every row and every column of right there is a call to right.rowconfigure(rowi, weight=1) (or to columnconfigure).
  • Every grid placement of every button b is made with sticky NSEW.
  • I have set right.grid_propagate(0)

What exactly am I doing wrong?

If I put the buttons directly onto top, the buttons just become wider than tall. It seems that they are being resized to accomodate propagated space. How do I prevent this resizing?

Impulsive answered 17/5, 2014 at 8:20 Comment(2)
If you want you buttons to be 1px by 1px perhaps consider using a canvas?Tennant
I don't want my buttons to be 1 pixel by 1 pixel, if that is what you meant. I just want my buttons to be squares, no matter what is inside them. Currently, they are only squares if the text is small enough, otherwise they get taller.Impulsive
R
9

If a Button displays text, when you use height and width options, their units in text unit. To make them square, using pixel unit would be better. To do that, you need to place that button in a Frame and make sure frame won't propagate(grid_propagate) and allow its children to fill it (columnconfigure & rowconfigure).

This is just an example, since I don't see your code.

import Tkinter as tk

master = tk.Tk()

frame = tk.Frame(master, width=40, height=40) #their units in pixels
button1 = tk.Button(frame, text="btn")


frame.grid_propagate(False) #disables resizing of frame
frame.columnconfigure(0, weight=1) #enables button to fill frame
frame.rowconfigure(0,weight=1) #any positive number would do the trick

frame.grid(row=0, column=1) #put frame where the button should be
button1.grid(sticky="wens") #makes the button expand

tk.mainloop()

EDIT: I just saw your edit(adding your code). After applying same things to your code;

import Tkinter, tkFont
top = Tkinter.Tk()
right = Tkinter.Frame(top)
right.pack(side = "right")
font = tkFont.Font(family="Helvetica", size=20, weight = tkFont.BOLD)

for i in xrange(6):
    f = Tkinter.Frame(right,width=50,height=50)
    b = Tkinter.Button(f, text = str(i), font = font)

    f.rowconfigure(0, weight = 1)
    f.columnconfigure(0, weight = 1)
    f.grid_propagate(0)

    f.grid(row = i/3, column = i%3)
    b.grid(sticky = "NWSE")

top.mainloop()
Rodrich answered 17/5, 2014 at 10:22 Comment(0)
G
4

Another method is to trick the Button into thinking it's displaying an image, so its units can be manipulated by pixels instead of text-size.

You can do this by creating an empty instance of PhotoImage, setting it to the image option of the button, and using the compound option of the button to combine the "image" and text. Here's an example using part of your code:

import Tkinter, tkFont


root = Tkinter.Tk()

font = tkFont.Font(family="Helvetica", size=60, weight = tkFont.BOLD)
blank_image = Tkinter.PhotoImage()

for i in xrange(6):
    b = Tkinter.Button(root, image=blank_image, text=str(i),
                       font=font, compound=Tkinter.CENTER)

    # get the height of the font to use as the square size
    square_size = font.metrics('linespace')
    b.config(width=square_size, height=square_size)

    b.grid(row = i/3, column = i%3, sticky = "NWSE")

root.mainloop()
Goosegog answered 17/5, 2014 at 15:0 Comment(0)
A
0

Its because 5x5 doesn't represent 5 pixels by 5 pixels, but 5 zero's by 5 zero's

it represents this:

00000
0
0
0
0
Artistic answered 20/4, 2023 at 14:11 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Sovereign

© 2022 - 2024 — McMap. All rights reserved.