-1

Im trying to make a tic-tac-toe game, but every time i run the program, the function is automatically executing for some reason. code so far below:

from tkinter import *

root = Tk()
root.geometry('200x200')

x_turn = True

def button_clicked(b):
    global x_turn
    print('Executed')
        if x_turn is True:
            b.config(text='X')
            x_turn = False
        else:
            b.config(text='O')
            x_turn = True

button1 = Button(root, text='', width=6, height=2)
button1.bind('<Button1>', button_clicked(button1))
button1.grid(row=0, column=0)

button2 = Button(root, text='', width=6, height=2)
button2.bind('<Button1>', button_clicked(button2))
button2.grid(row=0, column=1)

button3 = Button(root, text='', width=6, height=2)
button3.bind('<Button1>', button_clicked(button3))
button3.grid(row=0, column=2)

button4 = Button(root, text='', width=6, height=2)
button4.bind('<Button1>', button_clicked(button4))
button4.grid(row=1, column=0)

button5 = Button(root, text='', width=6, height=2)
button5.bind('<Button1>', button_clicked(button5))
button5.grid(row=1, column=1)

button6 = Button(root, text='', width=6, height=2)
button6.bind('<Button1>', button_clicked(button6))
button6.grid(row=1, column=2)

button7 = Button(root, text='', width=6, height=2)
button7.bind('<Button1>', button_clicked(button7))
button7.grid(row=2, column=0)

button8 = Button(root, text='', width=6, height=2)
button8.bind('<Button1>', button_clicked(button8))
button8.grid(row=2, column=1)

button9 = Button(root, text='', width=6, height=2)
button9.bind('<Button1>', button_clicked(button9))
button9.grid(row=2, column=2)

root.mainloop()

When i run the program it automatically calls the function 9 times and i cant figure out why. is there some wierd rule i dont know about?

jjguidry
  • 43
  • 1
  • 1
  • 9

1 Answers1

1

It automatically calls button_clicked 9 times, because you told it to call it 9 times with your 9 buttonX.bind... calls.

The bind method takes a function as a parameter. You're not passing in a function, you're passing in the return value from button_clicked(b).

[button_clicked is a function, but button_clicked(some_parameter) means calling that function, and using the return value as the parameter]

There are a few ways to pass in a function that takes parameters to the bind method. One way is to pass in an anonymous lambda expression that will call your real function when it is called.

So, instead of this:

button1.bind('<Button1>', button_clicked(button1))

change all your calls to look something like this:

button1.bind('<Button1>', lambda: button_clicked(button1)) 
Gerrat
  • 28,863
  • 9
  • 73
  • 101