Search code examples
pythonclassfor-looptkinternested-loops

Compacting my class for my tkinter window with buttons


I have an issue in that I can compact this code (I've been told I can) but did not receive any help in doing so and don't have a clue how to do it.

Tried putting this into a for loop, but I want a 3x3 grid of buttons with the middle one being a listbox instead, dead centre of the buttons.

I have looked around, and after an hour, I got no answer.

Here I tried appending each button to a list and packing them in a for loop, but is it possible to do them each in a for loop and the Listbox done and packed separately after?

class MatchGame(Toplevel):
    def __init__(self,master):
        self.fr=Toplevel(master)
        self.GameFrame=Frame(self.fr)
        self.AllButtons=[]
        self.AllButtons.append(Button(self.GameFrame,bg="red",height=5,width=15,text=""))
        self.AllButtons.append(Button(self.GameFrame,bg="green",height=5,width=15,text=""))
        self.AllButtons.append(Button(self.GameFrame,bg="dark blue",height=5,width=15,text=""))
        self.AllButtons.append(Button(self.GameFrame,bg="turquoise",height=5,width=15,text=""))
        self.AllButtons.append(Listbox(self.GameFrame,bg="grey",height=5,width=15))
        self.AllButtons.append(Button(self.GameFrame,bg="yellow",height=5,width=15,text=""))
        self.AllButtons.append(Button(self.GameFrame,bg="pink",height=5,width=15,text=""))
        self.AllButtons.append(Button(self.GameFrame,bg="orange",height=5,width=15,text=""))
        self.AllButtons.append(Button(self.GameFrame,bg="purple",height=5,width=15,text=""))
        for x in range(0,len(self.AllButtons)):
            AllButtons[x].grid(row=int(round(((x+1)/3)+0.5)),column=x%3)
        self.GameFrame.grid(row=0,column=0)
        Quit=Button(self.fr, text="Destroy This Game", bg="orange",command=self.fr.destroy)
        Quit.grid(row=1,column=0)

It needs to have individual colours, same size and all that, but I don't know what to do. I'm fairly new to classes, and I can't work out for the life of me how to make this window with compact code (not 9 lines for each object, then packing them all.)


Solution

  • If you want to dynamically create a 3x3 grid of buttons. Then a nested for-loop seems to be your best option.

    Example:

    import tkinter as tk
    
    root = tk.Tk()
    # List of your colours
    COLOURS = [['red', 'green', 'dark blue'],
               ['turquoise', 'grey', 'yellow'],
               ['pink', 'orange', 'purple']]
    
    # Nested for-loop for a 3x3 grid
    for x in range(3):
        for y in range(3):        
            if x == 1 and y == 1: # If statement for the Listbox
                tk.Listbox(root, bg = COLOURS[x][y], height=5, width=15).grid(row = x, column = y)
            else:
                tk.Button(root, bg = COLOURS[x][y], height=5, width=15).grid(row = x, column = y)
    
    root.mainloop()