1

I am creating a set of buttons via this function:

from tkinter import *
from random import randint

window = Tk()
window.title("Test")
window.geometry('200x200')
color = ["red","blue","green","yellow","black","purple","orange"]
RandInt = 0
j = 0
h = 0

def ButtonDef(xvar = 0,yvar = 0): 
    btn = Button(command =lambda:[RandomColor()])
    btn.grid()
    btn.place(x = xvar*50, y = yvar*50, width = 50, height = 50)

    def RandomColor():
        RandInt = randint (0,6)
        btn.configure(bg = color[RandInt])

while j in range (4):
    i = 0
    j += 1
    while i in range (4):
        ButtonDef(i,h)
        i += 1
        if i == 4:
            h += 1
window.mainloop()

However, my RandomColor() function is changing only the color of the very button i have pressed - that is fun too, but i wonder how i can make it randomly change the color of all buttons. When being created by a function, i would have guessed that all buttons that were created are named "btn" since thats the only name i have given them.

How could i address all (or one specific) buttons, out of a group of created-by-function buttons? Or to put it simply, what name do all of those buttons have? Do they share the name "btn"? Are they assigned a hidden ID?

3
  • Answer possibly related to this, im not sure: stackoverflow.com/questions/42599924/… Commented May 15, 2018 at 7:00
  • RandomColor is set to the command of your buttons, it not being called when you create them, it is called when the button is clicked. Commented May 15, 2018 at 7:50
  • Yes, that was my idea - i wanted to make a small game out of this later where specific colors had different actions or something like that. Or just get a flashy little disco-dancefloor :) Commented May 15, 2018 at 8:42

2 Answers 2

1

The reason behind your problem:

The problem is that when this line is executed: btn = Button(command =lambda:[RandomColor()]) by the end of the loop, you get a reference only to the last button which is created. You loose reference to other buttons.

Solution:

You can overcome this problem if you rely on winfo_children().

You have to do 2 steps to fix your issue:

First of all, change: btn = Button(command =lambda:[RandomColor()]) to btn = Button(window, command=lambda:[RandomColor()]). That simply means we attach each created button to a parent widget called window.

Then all that you need to change is RandomColor() function body as follows:

def RandomColor():       
    for child in window.winfo_children():
        child.configure(bg=color[randint(0,6)])

Demo:

enter image description here

This solves your problem but your code is not clean. You can ask for suggestions to improve your code on Code Review website.

EDIT:

Here is a solution for the scenario you described in the comment.

Note that I had to create code from scratch, cleaner one (I know you started only today, so I am not blaming you). In this code, I keep reference for every button I create:

import tkinter as tk
import random


class ChangeBottomRightColor(tk.Frame):

   def __init__(self, master):
       self.master = master
       tk.Frame.__init__(self, self.master)
       self.__colors = ["red","blue","green","yellow","black","purple","orange"]
       self.configure_gui()
       self.create_widgets()

   def configure_gui(self):
       pass

   def create_widgets(self):
       self.create_buttons()

   def create_buttons(self):
       self.buttons = {}
       c = 0
       for i in range(4):
           for j in range(4):              
               self.buttons['button{}'.format(c)] = tk.Button(self.master)
               self.buttons['button{}'.format(c)].grid(row=i, column=j)
               self.buttons['button{}'.format(c)].config(width=3, height=3)
               self.buttons['button{}'.format(c)].config(command=self.change_bottom_right_button_color)
               c += 1

   def get_random_color(self):
       return random.choice(self.__colors)

   def change_bottom_right_button_color(self):       
       self.buttons['button{}'.format(15)].config(bg=self.get_random_color())       



if __name__ == '__main__':
   root = tk.Tk()
   main_app =  ChangeBottomRightColor(root)
   root.mainloop()

Demo:

enter image description here

Sign up to request clarification or add additional context in comments.

7 Comments

I am aware that my code doesnt look good yet - im only a few hours into python, but still - thanks for the easy solution, may i ask what i would have to change if, lets say, i would only want the bottom-right button to change color upon clicking on any button? my initial question was rather generally how all of those generated buttons are "unique" as i did not generate them by, lets say, manually naming name btn1, btn2, btn3 and so on
Sorry, I do not understand your question because you did what you asked for yourself (the code in your question). Otherwise, please clarify me
with your solution, i can now recolor all buttons when clicking any button - but part of my question was "How could i address all (or one specific) buttons" and i still dont know how i can configure one specific button - lets imagine this scenario: i want to change the color of one button - lets say, the button in the bottom-right corner, when clicking on any other button. how would i do this? all i did in my original code was recolor the button i clicked, not recolor another button
Do you want a solution for the specific scenario you described?
If you have one sure, no problem if thats too much of a hastle
|
1

Let try

btn = []
for i in range(16):
    btn.append(Button(window))

it will create an array of button. So you can access by btn[i].configure(command=lambda:[RandomColor()]) or something else.

1 Comment

Where would i put this? Replace the btn = Button() part with this one?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.