Python Forum

Full Version: Tic Tac Toe
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I would need help regarding why Button callbacks don't work.

Here it is:

    def __init__(self, master):
        super().__init__(master)
        self.parent = master


        def right_click_X(event):
                self.buttons = buttons
                buttons["text"] = "X"

        def left_click_O(event):
                self.buttons = buttons
                buttons["text"] = "O"



        for i in range(4):
            for j in range(4):
                buttons = tk.Button(self, text="", height=6, width=12)
                buttons.grid(row=i, column=j)

                buttons.bind("<Button-3>", right_click_X)
                buttons.bind("<Button-1>", left_click_O)

                self.pack()
You want to grid everything to self.parent/master, the Tk() instance. Also the buttons variable overwrites the previous Button() instance so it only contains the last one (under the for). Also, the functions called by a button press are indented as members of the class, so they should be member, i.e "self" added where necessary.
import sys
if 3 == sys.version_info[0]: ## 3.X is default if dual system
    import tkinter as tk     ## Python 3.x
else:
    import Tkinter as tk     ## Python 2.x

from functools import partial

class ButtonTest():
    def __init__(self, master):
        self.parent = master
        ## instance attribute to store button instances
        self.buttons_list=[]

        for i in range(4):
            for j in range(4):
                ## unique number of this button, set as text=, and used in the callback
                ## to tell the function which button to use
                button_num=i*4+j
                button = tk.Button(self.parent, text="%d" % (button_num), height=6, width=12)
                button.grid(row=i, column=j)

                ## use partial to send args (button_num) to the function
                button.bind("<Button-3>", partial(self.right_click_X, button_num))
                button.bind("<Button-1>", partial(self.left_click_O, button_num) )

                ## store each Button() instance in a list
                self.buttons_list.append(button)

    def right_click_X(self, button_num, event):
        this_button=self.buttons_list[button_num]
        this_button["text"] = "X"
        this_button["bg"]="lightblue"

    def left_click_O(self, button_num, event):
        this_button=self.buttons_list[button_num]
        this_button["text"] = "O"
        this_button["bg"]="light salmon"

master=tk.Tk()
BT=ButtonTest(master)
master.mainloop()  
Thank you very much!