Python Forum
Centering labels and buttons
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Centering labels and buttons
#1
Hello Python Users:

I am a beginner with Python & Tkinter. I created 3 rows of labels and command buttons with the following code. I am kind of happy with the middle row. Sorry I couldn't figure out how to copy the screen so I could show you the result of running the program.

In the top how how do I the labels and buttons to expand so that 1)there is no space between them 2) their widths expand so that the 3 buttons take the entire width. -similar to the middle row?

In the 3rd row I would like the 2 command buttons to be centered all the way across.

I am a little familiar with pack and grid. Should I learn place?



from tkinter import *

root = Tk()



TL = Label(root, text="Top Left", bg="pale turquoise")
TL.grid(row =1, column = 0)]

TM= Button(root, text="Top Middle", bg="White")
TM.grid( row =1, column = 1)

TR  = Button(root, text="Top Right", bg="turquoise")
TR.grid( row =1, column = 2,)

ML = Button(root, text="Middle Left", bg="grey")
ML.grid( row =2, column = 0)

MMa = Button(root, text="MiddelMiddleA", bg="yellow")
MMa.grid( row =2, column = 1)

MMb = Button(root, text="MiddleMiddleb", bg="yellow")
MMb.grid( row =2, column = 2)

MMc = Button(root, text="MiddleMiddlec", bg="yellow")
MMc.grid(row =2, column = 3)

MMd = Button(root, text="MiddleMiddled", bg="yellow")
MMd.grid( row =2, column = 4)

MMe = Button(root, text="MiddleMiddlee", bg="yellow")
MMe.grid( row =2, column = 5)

BottomLeft = Button(root, text="BottomLeft", bg="deep pink")
BottomLeft.grid( row =3, column = 0)

BottomRight = Button(root, text="BottomRight", bg="red")
BottomRight.grid( row =3, column = 1)



root.mainloop()
Reply
#2
Video 
Is this what you want? I learned from this tutorial
https://python-forum.io/Thread-Tkinter-G...first-time

Your code modified:
#! /usr/bin/env python3

import tkinter as tk

root = tk.Tk()

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

mainframe = tk.Frame(root)
mainframe.grid(column=0, row=0, sticky='new')
mainframe.grid_columnconfigure(0, weight=3)

top = {'top left':'pale turquoise','top middle':'white','top right':'turquoise'}
mid = {'middle left':'grey','middle a':'yellow','middle b':'yellow','middle c':'yellow',
       'middle d':'yellow','middle e':'yellow'}
btm = {'bottom left':'deep pink','bottom right':'red'}

topframe = tk.Frame(mainframe)
topframe.grid(column=0, row=0, sticky='new')
for i in range(len(top)):
    topframe.grid_columnconfigure(i, weight=3, uniform='top')

midframe = tk.Frame(mainframe)
midframe.grid(column=0, row=1, sticky='new')
for i in range(len(mid)):
    midframe.grid_columnconfigure(i, weight=3, uniform='middle')

btmframe = tk.Frame(mainframe)
btmframe.grid(column=0, row=2, sticky='new')
for i in range(len(btm)):
    btmframe.grid_columnconfigure(i, weight=3, uniform='bottom')

col = 0
for key, value in top.items():
    btn = tk.Button(topframe, text=key.title())
    btn['bg'] = value
    btn.grid(column=col, row=0, sticky='new')
    col += 1

col = 0
for key, value in mid.items():
    btn = tk.Button(midframe, text=key.title())
    btn['bg'] = value
    btn.grid(column=col, row=0, sticky='new')
    col += 1

col = 0
for key, value in btm.items():
    btn = tk.Button(btmframe, text=key.title())
    btn['bg'] = value
    btn.grid(column=col, row=0, sticky='new')
    col += 1


root.mainloop()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#3
Thanks Menator01,

Your code does what I want. It seems quite complicated but I can use it without understanding it. Hope to understand it eventually.
Reply
#4
Just using grids to make the buttons stretch. The rest is too keep from repeating the code so much.
The tutorial will teach how to properly use grids.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#5
(Jul-16-2020, 12:14 AM)Heyjoe Wrote: Thanks Menator01,

Your code does what I want. It seems quite complicated but I can use it without understanding it. Hope to understand it eventually.
Complicated or silly. I'm having a hard time deciding.

I understand the dictionary of labels and colors, but it is a really odd way to write a program. About half way between specifying the interface using a template (not enough indirection or genericity), and hard coding each control independently (not as much freedom). I don't see it offering much advantage.

But don't let the dictionary turn you off. There are other good ideas here. The way the program uses frames so you can have a different number of buttons in each row is very nice. If all controls were in the same grid, they will only align on the grid. This doesn't work well when one row has 3 buttons and another has two.

This should be a great example of when pack is a better fit than grid. This would be really easy to do in Qt, but it doesn't work quite right in tkinter.
import tkinter as tk
 
root = tk.Tk()

def row(parent, **kvargs):
    row = tk.Frame(parent, **kvargs)
    row.pack(expand=1, fill='both', padx=5, pady=5)
    return row

def thing(thing_type, parent, **kvargs):
    thing = thing_type(parent, **kvargs)
    thing.pack(side='left', expand=1, fill='both', padx=5, pady=5)
    return thing

# Layout widgets
vbox = tk.Frame(root)
vbox.pack(expand=1, fill='both', padx=5, pady=5)

# Top row 
hbox = row(vbox)
TL = thing(tk.Label, hbox, text="Top Left", bg="pale turquoise")
TM = thing(tk.Button, hbox, text="Top Middle", bg="White")
TR = thing(tk.Button, hbox, text="Top Right", bg="turquoise") 

hbox = row(vbox)
ML  = thing(tk.Button, hbox, text="Middle Left", bg="grey")
MMa = thing(tk.Button, hbox, text="Middle A", bg="yellow")
MMb = thing(tk.Button, hbox, text="Middle B", bg="yellow")
MMc = thing(tk.Button, hbox, text="Middle C", bg="yellow") 
MMd = thing(tk.Button, hbox, text="Middle D", bg="yellow") 
MMe = thing(tk.Button, hbox, text="Middle E", bg="yellow")
 
hbox = row(vbox)
BottomLeft = thing(tk.Button, hbox, text="BottomLeft", bg="deep pink") 
BottomRight = thing(tk.Button, hbox, text="BottomRight", bg="red")

root.mainloop()
Run this code and you see that it isn't quite right. The middle space in row 2 doesn't quite line up with the middle space in row 3. And this is because I cannot find a way to tell frame to make all children the same width using pack. Menator01 gets this from using grid and setting the column weight the same for each column. The only way I could find to make all controls the same size is to set the initial width explicitly to be the same.

I too will write silly code to avoid typing.
Reply
#6
(Jul-16-2020, 02:26 AM)deanhystad Wrote: Complicated or silly. I'm having a hard time deciding.

I understand the dictionary of labels and colors, but it is a really odd way to write a program. About half way between specifying the interface using a template (not enough indirection or genericity), and hard coding each control independently (not as much freedom). I don't see it offering much advantage.

But don't let the dictionary turn you off. There are other good ideas here. The way the program uses frames so you can have a different number of buttons in each row is very nice. If all controls were in the same grid, they will only align on the grid. This doesn't work well when one row has 3 buttons and another has two.

This should be a great example of when pack is a better fit than grid. This would be really easy to do in Qt, but it doesn't work quite right in tkinter.

Run this code and you see that it isn't quite right. The middle space in row 2 doesn't quite line up with the middle space in row 3. And this is because I cannot find a way to tell frame to make all children the same width using pack. Menator01 gets this from using grid and setting the column weight the same for each column. The only way I could find to make all controls the same size is to set the initial width explicitly to be the same.

I too will write silly code to avoid typing.

The dict. was just to reduce the redundant typing. It was used as an example and kind of an experiment too. As I am still learning.
Using tkinter I would rather use grids as I had pack. It's a lot easier to get things to align.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#7
I'm not sure I fully understand what you're describing, but it sounds a bit similar to this use of grid with entry boxes. It's about creating a table like arrangement of entry-boxes with no gap in between them to act as a spread sheet.
Reply
#8
I think what you need is to change the width and height parameters of the buttons,
width=..., height=...
Reply
#9
Setting button size and placment is the job of a layout manager. If you never want to resize a window you can do it yourself, but it makes you GUI code very brittle. What if you want to change a font or an image? What if you want to use styling? Using layout management the program will take in all the changes and do a good job at maintaining the layout.

If you are using width and height in your GUI programs you are doing something wrong.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Centering and adding a push button to a grid window, TKinter Edward_ 15 4,375 May-25-2023, 07:37 PM
Last Post: deanhystad
  Matplotlib figsize and centering issue on canvas deffonotsean 0 1,800 Jun-10-2020, 10:31 AM
Last Post: deffonotsean

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020