update tkinter label with mouse click
Question: I am the beginner in Python and am trying to code a tictactoe game with
`tkinter`. My class named `Cell` extends `Tkinter.Label`. The `Cell` class
contains data fields `emptyLabel`, `xLabel` and `oLabel`. This is my code so
far for class `Cell`:

    
    
    from tkinter import *
    
    class Cell(Label):
        def __init__(self,container):
            super().__init__(container)
            self.emptyImage=PhotoImage(file="C:\\Python34\\image\\empty.gif")
            self.x=PhotoImage(file="C:\\Python34\\image\\x.gif")
            self.o=PhotoImage(file="C:\\Python34\\image\\o.gif")
    
        def getEmptyLabel(self):
            return self.emptyImage
    
        def getXLabel(self):
            return self.x
    
        def getOLabel(self):
            return self.o
    

and my main class is as follows:

    
    
    from tkinter import *
    from Cell import Cell
    
    class MainGUI:
        def __init__(self):
            window=Tk()
            window.title("Tac Tic Toe")
    
            self.frame1=Frame(window)
            self.frame1.pack()
    
            for i in range (3):
                for j in range (3):
                    self.cell=Cell(self.frame1)
                    self.cell.config(image=self.cell.getEmptyLabel())
    
                    self.cell.grid(row=i,column=j)
    
            self.cell.bind("<Button-1>",self.flip)
    
            frame2=Frame(window)
            frame2.pack()
            self.lblStatus=Label(frame2,text="Game Status").pack()
    
            window.mainloop()
    
       def flip(self,event):
           self.cell.config(image=self.cell.getXLabel())
    
    MainGUI()
    

The code displays an empty cell image on cell 3x3, but when I click the cell
to update the empty cell image to X image. It currently only happens on the
empty label in row 3 column 3.

My question is: How to change the label on a mouse click?


Answer: You keep reassigning `self.cell`, and then when that part is done you bind a
mouse button to the last cell. Bind the mouse button to each cell within the
loop.

The callback function is also hard-coded to only look at `self.cell`, which
you kept reassigning to end up with only the last one. In addition to binding
the mouse button to each cell, you'll have to change the callback function to
look at the proper cell.

In `__init__`:

    
    
    for i in range (3):
        for j in range (3):
            cell=Cell(self.frame1)
            cell.config(image=self.cell.getEmptyLabel())
    
            cell.grid(row=i,column=j)
    
            cell.bind("<Button-1>", lambda event, cell=cell: self.flip(cell))
    

Or, without using `lambda`:

    
    
    for i in range (3):
        for j in range (3):
            cell=Cell(self.frame1)
            cell.config(image=self.cell.getEmptyLabel())
    
            cell.grid(row=i,column=j)
    
            def temp(event, cell=cell):
                self.flip(cell)
    
            cell.bind("<Button-1>", temp)
    

In `flip`:

    
    
    def flip(self, cell):
        self.cell.config(image=cell.getXLabel())
    

