How do I wait for a certain number of buttons to be clicked in Tkinter/Python?
Question: I'm trying to write a simple 'Simon' game, but I have hit a road block here,
and honestly have no idea how to get around it.

So here, I made a class for the four buttons in the GUI:

    
    
    class button:
        def buttonclicked(self):
                self.butclicked= True
    
        def checkIfClicked(self):
                if self.butclicked== True:
                        global pressed
                        pressed.append(self.color)
                        self.butclicked= False
    
        def __init__(self, color1):
                self.color= color1
            self.button= tk.Button(root, text=' '*10, bg= self.color, command= self.buttonclicked)
            self.button.pack(side='left')
            self.butclicked=False
    

I then created four instances of this class in `blue, red, yellow, and green
as bb, rb, yb,` and `gb`.

Once everything is packed into the Tk() module, it enters a while loop that
appends a random color to a list activecolors. I try to use the following loop
to wait until the list pressed is at least as long as the list activecolors
before comparing the two to see if the user was correct:

    
    
    while len(pressed)<len(activecolors):
                        sleep(.25)
                        print('In the check loop')
                        bb.checkIfClicked()
                        rb.checkIfClicked()
                        yb.checkIfClicked()
                        gb.checkIfClicked()
    

However, since it is stuck inside the while loop, the program can't tell that
the button has been clicked. I thought adding the sleep method into the loop
would allow the code to have time to do other things (such as process button
clicks), but this is not the case. Any help is appreciated.

[Here is the
link](https://docs.google.com/document/d/16zQlQk_mFoSro7iq_8NDYWen2QwfhGNUgcs7JSkFwvU/edit?usp=sharing)
to the full code, if you would like to see it. A warning though: it's not
pretty.

Edit: I ended up just changing the code to check the list only after a new
button was clicked, telling the computer the code was ready. I've updated the
Google Document if you'd like to see it.


Answer: You are making it too complicated. This program uses partial from
functiontools to allow a variable to be passed to the function so one function
handles all clicks (Python 2.7).

    
    
    from Tkinter import *
    from functools import partial
    
    class ButtonsTest:
        def __init__(self):
            self.top = Tk()
            self.top.title('Buttons Test')
            self.top_frame = Frame(self.top, width =400, height=400)
            self.colors = ("red", "green", "blue", "yellow")
            self.colors_selected = []
            self.num_clicks = 0
            self.wait_for_number = 5
            self.buttons()
            self.top_frame.grid(row=0, column=1)
    
            Button(self.top_frame, text='Exit', 
             command=self.top.quit).grid(row=2,column=1, columnspan=5)
    
            self.top.mainloop()
    
        ##-------------------------------------------------------------------         
        def buttons(self):
            for but_num in range(4):
                b = Button(self.top_frame, text = str(but_num+1), 
                      command=partial(self.cb_handler, but_num))
                b.grid(row=1, column=but_num+1)
    
        ##----------------------------------------------------------------
        def cb_handler( self, cb_number ):
            print "\ncb_handler", cb_number
            self.num_clicks += 1
            this_color = self.colors[cb_number]
            if (self.num_clicks > self.wait_for_number) \
                 and (this_color in self.colors_selected):
                print "%s already selected" % (this_color)
            self.colors_selected.append(this_color)
    
    ##===================================================================
    BT=ButtonsTest()
    

