Changing button colors after click

Asked

Viewed 149 times

2

Good afternoon friends, I am starting the studies in python and need to do a job using Tkinter. I have 64 buttons and I must change their colors according to the user’s click. It has 6 color options, and when it clicks on one of them, the first of the 64 buttons has to get the color clicked, and so on, until the 64 buttons are colored. However, my code is only changing the last of the 64 buttons, and I am not able to fix it. I will leave the program print and the code. From now on, thank you. Tela que deve ser corrigida

Function called

    def getCorAtual(corAtual):
        desenho.configure(bg=corAtual)
        print(corAtual)
        boxCorAtual.configure(bg=corAtual)

Buttons on the left

    cor1 = tk.Button(coresWrap, bg='#ffffff', width=10, height=5, command=lambda: 
    getCorAtual('#ffffff'))
    cor1.grid(column=0, row=0)
    cor2 = tk.Button(coresWrap, bg='#000000', width=10, height=5, command=lambda: 
    getCorAtual('#000000'))
    cor2.grid(column=1, row=0)
    cor3 = tk.Button(coresWrap, bg='#ff0000', width=10, height=5, command=lambda: 
    getCorAtual('#ff0000'))
    cor3.grid(column=0, row=1)
    cor4 = tk.Button(coresWrap, bg='#0000ff', width=10, height=5, command=lambda: 
    getCorAtual('#0000ff'))
    cor4.grid(column=1, row=1)
    cor5 = tk.Button(coresWrap, bg='#00ff00', width=10, height=5, command=lambda: 
    getCorAtual('#00ff00'))
    cor5.grid(column=0, row=2)
    cor6 = tk.Button(coresWrap, bg='#ffff00', width=10, height=5, command=lambda: 
    getCorAtual('#ffff00'))
    cor6.grid(column=1, row=2)

Window creation

    containerDesenho = tk.Label(janela, bg='#e3e3e3')
    containerDesenho.place(x=200, y=0, width=600, height=800)

    tela = tk.Label(containerDesenho, bg='#e3e3e3')
    tela.place(width=600, height=700, x=30, y=10)

Buttons that should be colored

    for i in range(1, 9):
        for j in range(1, 9):
            desenho = tk.Button(tela, bg='white', width=8, height=4)
            desenho["command"] = lambda x=j, y=i: getBotao(x, y)
            desenho.grid(column=j, row=i)
  • Hi, the idea is that when a button is clicked on the left side all the right side should be colored with the button color pressed?

  • @Williamteixeira exactly that, go coloring from left to right until everyone gets colored.

1 answer

1


Explanation

Basically when you create multiple buttons assigned to a single variable you will not be able to access and edit them later. Ex.: If you define:

a = 1
print(a)

Resultado: 1

But if you define:

a = 1
a = 2
print(a)

Resultado: 2

The same thing happens for a loop

a = 0
for c in range(4):
    a = c
    print(c, end = ' - ')

print(c)

Resultado: 0 - 1 - 2 - 3 - 3

Note that when you exit the loop when you display the variable a on the screen it shows only the last value, which was 3, it means that a variable is limited, and is restricted to only one value, is like a little box that only fits one item, when defining a = 1 the box is with the item 1, but then I define a = 2 the box will no longer have the item 1 and will contain the item 2, a list is like a larger box, where I can place the 2 items (or more, depending on your need), lista = [1, 2], you are the one who defines the list size. Now I’m gonna cut the bullshit and go straight to the solution!

Solution

The most viable route I could find was using lists. To start you will have to declare a list with 8 more lists inside, basically each list contained within the main list is a line of the drawing area, would look like this: tabela = [[], [], [], [], [], [], [], []], the "table" list is the entire drawing area, and the lists contained within it are the lines in the drawing area, e.g..: tabela[0] == Linha1. The next step would be to change the form that creates the buttons, instead of creating buttons assigned to a variable, it would add and store the buttons in order in the "table" list, like this:

for i in range(8):
    for j in range(8):
        tabela[i].append(Button(root, bg = '#ffffff', width = 8, height = 4))
        tabela[i][j].config(command = lambda x = j, y = i: getBotao(x, y))
        tabela[i][j].grid(column = j, row = i)

Next you would create 2 global variables

cont_column = 0
cont_line = 0

Preferably at the beginning of the program, outside any function

The cont_column will count the columns and the cont_line the lines

The function getCorAtual would look like this:

def getCorAtual(corAtual):
    # Específica que as variáveis são globais
    global tabela
    global boxCorAtual
    global cont_column
    global cont_line

    # Se chegou no fim da área do desenho ele começa a substituir as cores do início
    if cont_line == len(tabela) - 1 and cont_column == len(tabela[cont_line]):
        cont_line = 0
        cont_column = 0

    # Se chegou no fim da linha ele irá pular para a próxima linha e começar a preencher as colunas do zero
    if cont_column == len(tabela[cont_line]):
        cont_column = 0
        cont_line += 1

    tabela[cont_column][cont_line].configure(bg=corAtual)
    print(corAtual)
    boxCorAtual.configure(bg=corAtual)
    cont_column += 1

I hope I helped. Good studies!

  • 1

    Paul, that’s exactly what I needed, it worked perfectly! Thank you so much for your help!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.