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

Time:12-25

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()

CodePudding user response:

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**

CodePudding user response:

What you need to add Drip.map.

Drip.configure('TButton',background='Black',foreground='Gold') #The style that I want to keep 
Drip.map('TButton', background=[('active', 'black')]) 
  • Related