Tkinter GUI grid system: how to expand a button

How to make an interface with a lot of buttons and make it work. I made also the button to fit the window when it is resized. It is not so intuitive the way to do it, but finally the code is below here. I had to use the Grid class rowconfigure method and also a frame to make it work right, otherwise the button would stretch horizzontally, but not vertically (only the first one would stretch, or one and not all the others).

So, here we are, the second part of the button with tkinter tutorial (kinda of). Now we will check how to put an image in a button (we’ve seen this, but into a script that was a little complicated, now we are making things a little simpler) and how to RESIZE it, or expand it until it fills the window in the grid syste. The grid method is different from the pack method, so here is the final code and then you got the video.

import os
import tkinter as tk
import tkinter.ttk as ttk


root = tk.Tk()
root.title("Lanch my Programs")


class Button:
    """button1 = Button("Testo", "4ce", 0, 0)"""
    row = 0
    def __init__(self, text, func, image=""):
        image = tk.PhotoImage(file=image)
        tk.Grid.rowconfigure(root, Button.row, weight=1)
        tk.Grid.columnconfigure(root, 0, weight=1)

        self.button = tk.Button(
            root,
            text=text,
            image=image,
            compound = tk.LEFT,
            command=func)
        # self.button.pack()
        self.button.grid(sticky="nswe")
        self.button.image = image
        Button.row += 1

    def open(text):
        os.startfile(text)


data = [
    ["Text 1", lambda: Button.open("example.txt"), "notepad.PNG"],
    ["Text 2", lambda: Button.open("example2.txt"), "notepad.PNG"],
]

for d in data:
    b = Button(*d)

root.mainloop()

Without the frame

I made this code that can resize the buttons without the frame.

import os
import tkinter as tk
import tkinter.ttk as ttk


root = tk.Tk()
root.title("Lanch my Programs")


class Button:
    """button1 = Button("Testo", "4ce", 0, 0)"""
    row = 0
    def __init__(self, text, func, image=""):
        image = tk.PhotoImage(file=image)
        tk.Grid.rowconfigure(root, Button.row, weight=1)
        tk.Grid.columnconfigure(root, 0, weight=1)

        self.button = tk.Button(
            root,
            text=text,
            image=image,
            compound = tk.LEFT,
            command=func)
        # self.button.pack()
        self.button.grid(sticky="nswe")
        self.button.image = image
        Button.row += 1

    def open(text):
        os.startfile(text)


data = [
    ["Text 1", lambda: Button.open("example.txt"), "notepad.PNG"],
    ["Text 2", lambda: Button.open("example2.txt"), "notepad.PNG"],
]

for d in data:
    b = Button(*d)

root.mainloop()

Fit perfectly the window video

This is the video of the updated code to fit the window.

Where is the trick?

The trick here is to use the rowconfigure and columnconfigure method in root, otherwise the sticky=”nsew” won’t work.

Simply resizable buttons (without class)

If you just want to add buttons that are resizable, but you do not want to create a class, like in the code above, I will show you some very basic code that will also help you to better understand the way you can configure the rowconfigure and column configure. You have to put the number of the row and the column right to affect all the button both in width and height. As the column remain the same (if you do not specify differently), the row needs to be changed to 0, 1, 2…

import tkinter as tk
import tkinter.ttk as ttk


root = tk.Tk()
root.title("Lanch my Programs")

tk.Grid.rowconfigure(root, 0, weight=1)
tk.Grid.columnconfigure(root, 0, weight=1)
image = tk.PhotoImage(file="plus.png")
b1 = tk.Button(
            root,
            text="Button1",
            image=image,
            compound = tk.LEFT,
            command=None)
b1.grid(sticky="nswe")

tk.Grid.rowconfigure(root, 1, weight=1)
b2 = tk.Button(
            root,
            text="Button2",
            image=image,
            compound = tk.LEFT,
            command=None)
b2.grid(sticky="nswe")

tk.Grid.rowconfigure(root, 2, weight=1)
b3 = tk.Button(
            root,
            text="Button3",
            image=image,
            compound = tk.LEFT,
            command=None)
b3.grid(sticky="nswe")


root.mainloop()

You can decide which of the buttons must resize specifying the rowconfigure and columncofigure coordinates of the button.

In the following example, the button in the middle will not resize

import tkinter as tk
import tkinter.ttk as ttk


root = tk.Tk()
root.title("Lanch my Programs")
tk.Grid.rowconfigure(root, 0, weight=1)
tk.Grid.columnconfigure(root, 0, weight=1)
image = tk.PhotoImage(file="plus.png")
b1 = tk.Button(
            root,
            text="Button1",
            image=image,
            compound = tk.LEFT,
            command=None)
b1.grid(sticky="nswe")

# THIS ONE DOES NOT RESIZE vertically, BECAUSE THERE IS NOT tk.Grid.rowconfigure(root, 1, wheight=1)
b2 = tk.Button(
            root,
            text="Button2",
            image=image,
            compound = tk.LEFT,
            command=None)
b2.grid(sticky="nswe")
tk.Grid.rowconfigure(root, 2, weight=1)
b3 = tk.Button(
            root,
            text="Button3",
            image=image,
            compound = tk.LEFT,
            command=None)
b3.grid(sticky="nswe")


root.mainloop()

Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.