Search code examples
pythonuser-interfacetkintertkinter-button

How to Disable a button while keeping the style in tkinter?


I made this simple Tic Tac Toe game code but I Encountered a problem when it comes to disabling a button. The buttons have a style attached to them, but after the player choses a button and it get's disabled, the button's background changes from Black to Grey. I want the button chosen by the player to maintain both the background color assigned to it and it's disabled status.

from tkinter import *
from tkinter import ttk

root=Tk()
root.title("Turn: P1")


Drip=ttk.Style()
Drip.theme_use('classic')
Drip.configure('TButton',background='Black',foreground='Gold') #The style that I want to keep 

ActivePlayer=1
Player1=[]
Player2=[]


def Bu_Click(Index):
    global ActivePlayer
    global Player1
    global Player2
    if ActivePlayer==1:
        Set_Symbol(Index,"X")
        Player1.append(Index)
        root.title("Turn: P2")
        ActivePlayer=2
        print(f'P1{Player1}')
    elif ActivePlayer==2:
        Set_Symbol(Index,"O")
        Player2.append(Index)
        root.title("Turn: P1")
        ActivePlayer=1
        print(f'P2{Player2}')
    Check_Win()

def Set_Symbol(Index,Symbol): # Button changes status and layout
    if Index==1:
        Bu1.config(text=Symbol)
        Bu1.state(['disabled']) 
    elif Index==2:
        Bu2.config(text=Symbol)
        Bu2.state(['disabled'])
    elif Index==3:
        Bu3.config(text=Symbol)
        Bu3.state(['disabled'])
    elif Index==4:
        Bu4.config(text=Symbol)
        Bu4.state(['disabled'])
    elif Index==5:
        Bu5.config(text=Symbol)
        Bu5.state(['disabled'])
    elif Index==6:
        Bu6.config(text=Symbol)
        Bu6.state(['disabled'])
    elif Index==7:
        Bu7.config(text=Symbol)
        Bu7.state(['disabled'])
    elif Index==8:
        Bu8.config(text=Symbol)
        Bu8.state(['disabled'])
    elif Index==9:
        Bu9.config(text=Symbol)
        Bu9.state(['disabled'])


def Check_Win():
    Winner=-1
    if( (1 in Player1) and (2 in Player1) and (3 in Player1)):
        Winner=1
    if 4 in Player1 and 5 in Player1 and 6 in Player1:
        Winner=1
    if 7 in Player1 and 8 in Player1 and 9 in Player1:
        Winner=1
    if 1 in Player1 and 4 in Player1 and 7 in Player1:
        Winner=1
    if 2 in Player1 and 5 in Player1 and 8 in Player1:
        Winner=1
    if 3 in Player1 and 6 in Player1 and 9 in Player1:
        Winner=1
    if 1 in Player1 and 5 in Player1 and 9 in Player1:
        Winner=1
    if 3 in Player1 and 5 in Player1 and 7 in Player1:
        Winner=1
    
    if 1 in Player2 and 2 in Player2 and 3 in Player2:
        Winner=2
    if 4 in Player2 and 5 in Player2 and 6 in Player2:
        Winner=2
    if 7 in Player2 and 8 in Player2 and 9 in Player2:
        Winner=2
    if 1 in Player2 and 4 in Player2 and 7 in Player2:
        Winner=2
    if 2 in Player2 and 5 in Player2 and 8 in Player2:
        Winner=2
    if 3 in Player2 and 6 in Player2 and 9 in Player2:
        Winner=2
    if 1 in Player2 and 5 in Player2 and 9 in Player2:
        Winner=2
    if 3 in Player2 and 5 in Player2 and 7 in Player2:
        Winner=2
    
    if Winner==1:
        win_message=Tk()
        mes=ttk.Label(win_message,text="Player 1 Won",width=50).pack()
    if Winner==2:
        win_message=Tk()
        mes=ttk.Label(win_message,text="Player 2 Won",width=50).pack()


Bu1=ttk.Button(root,text='')
Bu1.grid(row=0,column=0,sticky='snew',ipadx=40,ipady=40)

Bu2=ttk.Button(root,text='')
Bu2.grid(row=0,column=1,sticky='snew',ipadx=40,ipady=40)

Bu3=ttk.Button(root,text='')
Bu3.grid(row=0,column=2,sticky='snew',ipadx=40,ipady=40)

Bu4=ttk.Button(root,text='')
Bu4.grid(row=1,column=0,sticky='snew',ipadx=40,ipady=40)

Bu5=ttk.Button(root,text='')
Bu5.grid(row=1,column=1,sticky='snew',ipadx=40,ipady=40)

Bu6=ttk.Button(root,text='')
Bu6.grid(row=1,column=2,sticky='snew',ipadx=40,ipady=40)

Bu7=ttk.Button(root,text='')
Bu7.grid(row=2,column=0,sticky='snew',ipadx=40,ipady=40)

Bu8=ttk.Button(root,text='')
Bu8.grid(row=2,column=1,sticky='snew',ipadx=40,ipady=40)

Bu9=ttk.Button(root,text='')
Bu9.grid(row=2,column=2,sticky='snew',ipadx=40,ipady=40)


Bu1.config(command=lambda:Bu_Click(1))
Bu2.config(command=lambda:Bu_Click(2))
Bu3.config(command=lambda:Bu_Click(3))
Bu4.config(command=lambda:Bu_Click(4))
Bu5.config(command=lambda:Bu_Click(5))
Bu6.config(command=lambda:Bu_Click(6))
Bu7.config(command=lambda:Bu_Click(7))
Bu8.config(command=lambda:Bu_Click(8))
Bu9.config(command=lambda:Bu_Click(9))


root.mainloop()

Solution

  • Your Aim Can be achieved by:

    Bu1= Button(root, background="Black", activebackground="black",activeforeground="#fff", disabledforeground="#fff")  
    

    Using this above piece of code to make the button and

    Bu1["state"] = "disabled"
    

    Use this code to disable your button If you are using then you don't have to make Drip

    Drip=ttk.Style() Drip.theme_use('classic') Drip.configure('TButton',background='Black',foreground='Gold') #The style that I want to keep

    Also, I saw your code you are just repeating a line so many times to do the job while it can be done with for loop So I organized your code :)

    from tkinter import *
    from tkinter import ttk
    import tkinter as tk
    
    root = tk.Tk()
    root.title("Turn: P1")
    
    
    ActivePlayer = 1
    board = [
        [' ', ' ', ' '],
        [' ', ' ', ' '],
        [' ', ' ', ' ']
    ]
    
    
    def Bu_Click(button, x, y):
        global ActivePlayer
    
        if ActivePlayer == 1:
            Set_Symbol(button, "X")
            # Player1.append(Index)
            board[x][y] = 1
            root.title("Turn: P2")
            ActivePlayer = 2
    
        elif ActivePlayer == 2:
            Set_Symbol(button, "O")
            board[x][y] = 2
            root.title("Turn: P1")
            ActivePlayer = 1
    
        Check_Win(board)
    
    
    def Set_Symbol(button, Symbol):  # Button changes status and layout
        button.config(text=Symbol)
        button["state"] = "disabled"
    
    
    def show_win(player):
        win_message = Tk()
        mes = ttk.Label(win_message,
                        text=f"Player {str(player)} won this game!", width=50).pack()
    
    
    def Check_Win(board):
        # check rows
        for row in board:
            if row[0] == row[1] == row[2] and row[0] != ' ':
                show_win(row[0])
    
        # check columns
        for col in range(3):
            if board[0][col] == board[1][col] == board[2][col] and board[0][col] != ' ':
                show_win(board[0][col])
    
        # check diagonals
        if board[0][0] == board[1][1] == board[2][2] and board[0][0] != ' ':
            show_win(board[0][0])
    
        if board[0][2] == board[1][1] == board[2][0] and board[0][2] != ' ':
            show_win(board[0][2])
    
        return ' '
    
    
    # 9 is the number of buttons
    buttons = []
    for button_row in range(3):
        buttons.append([])
        for button_column in range(3):
            Button_obj = Button(root, background="Black", activebackground="black",
                                activeforeground="#fff", disabledforeground="#fff")
    
            Button_obj.grid(row=button_row, column=button_column,
                            sticky='snew', ipadx=40, ipady=40)
    
            buttons[button_row].append(Button_obj)
    
    
    buttons[0][0].config(command=lambda: Bu_Click(buttons[0][0], 0, 0))
    buttons[0][1].config(command=lambda: Bu_Click(buttons[0][1], 0, 1))
    buttons[0][2].config(command=lambda: Bu_Click(buttons[0][2], 0, 2))
    buttons[1][0].config(command=lambda: Bu_Click(buttons[1][0], 1, 0))
    buttons[1][1].config(command=lambda: Bu_Click(buttons[1][1], 1, 1))
    buttons[1][2].config(command=lambda: Bu_Click(buttons[1][2], 1, 2))
    buttons[2][0].config(command=lambda: Bu_Click(buttons[2][0], 2, 0))
    buttons[2][1].config(command=lambda: Bu_Click(buttons[2][1], 2, 1))
    buttons[2][2].config(command=lambda: Bu_Click(buttons[2][2], 2, 2))
    
    
    root.mainloop()
    

    ** Hope It Will Help You**