Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
101 views
in Technique[技术] by (71.8m points)

python - How to update the image of a specific button when it's clicked on?

from tkinter import *

# Creating the main window
topper = Tk()
topper.geometry('414x417')
topper.resizable(False, False)
topper.configure(bg='green')

# Importing all images that'll be used
b7_img = PhotoImage(file="C:\project images\b7.png")
b8_img = PhotoImage(file="C:\project images\b8.png")
b9_img = PhotoImage(file="C:\project images\b9.png")
b4_img = PhotoImage(file="C:\project images\b4.png")
b5_img = PhotoImage(file="C:\project images\b5.png")
b6_img = PhotoImage(file="C:\project images\b6.png")
b1_img = PhotoImage(file="C:\project images\b1.png")
b2_img = PhotoImage(file="C:\project images\b2.png")
b3_img = PhotoImage(file="C:\project images\b3.png")
bX_img = PhotoImage(file="C:\project images\bX.png")
bO_img = PhotoImage(file="C:\project images\bO.png")

# This determines if it's player 1's or player 2's turn to give an input
player_turn = False

# This is the function that's supposed to replace/update the image of the designated button on-click
def btn_click(button):
    global player_turn
    if player_turn:
        button(image=bO_img)
        player_turn = True
    if not player_turn:
        button(image=bX_img)
        player_turn = False


b7 = Button(topper, height='114', width='115', image=b7_img, command=lambda: btn_click(b7)).place(x=0, y=0)
b8 = Button(topper, height='114', width='115', image=b8_img, command=lambda: btn_click(b8)).place(x=150, y=0)
b9 = Button(topper, height='114', width='115', image=b9_img, command=lambda: btn_click(b9)).place(x=300, y=0)
b4 = Button(topper, height='114', width='115', image=b4_img, command=lambda: btn_click(b4)).place(x=0, y=150)
b5 = Button(topper, height='114', width='115', image=b5_img, command=lambda: btn_click(b5)).place(x=150, y=150)
b6 = Button(topper, height='114', width='115', image=b6_img, command=lambda: btn_click(b6)).place(x=300, y=150)
b1 = Button(topper, height='114', width='115', image=b1_img, command=lambda: btn_click(b1)).place(x=0, y=300)
b2 = Button(topper, height='114', width='115', image=b2_img, command=lambda: btn_click(b2)).place(x=150, y=300)
b3 = Button(topper, height='114', width='115', image=b3_img, command=lambda: btn_click(b3)).place(x=300, y=300)


topper.mainloop()

Hi everyone, I am trying to create a simple tic-tac-toe game with Tkinter but I am facing an issue, I can't update the image of the designated button when the player clicks on it, I can't change the image keyword argument for the designated button using the btn_click function, whenever I try to it'll give TypeError: 'NoneType' object is not callable

Is there any way I can solve the issue instead of having to create a specialized function for each button? Thanks.

question from:https://stackoverflow.com/questions/65911737/how-to-update-the-image-of-a-specific-button-when-its-clicked-on

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are three issues in your code:

  1. assigned result of place() (which always be None) to bX in line like b7 = Button(...).place(...). You need to separate the line into 2 statements:
b7 = Button(topper, height='114', width='115', image=b7_img, command=lambda: btn_click(b7))
b7.place(x=0, y=0)
b8 = Button(topper, height='114', width='115', image=b8_img, command=lambda: btn_click(b8))
b8.place(x=150, y=0)
b9 = Button(topper, height='114', width='115', image=b9_img, command=lambda: btn_click(b9))
b9.place(x=300, y=0)
b4 = Button(topper, height='114', width='115', image=b4_img, command=lambda: btn_click(b4))
b4.place(x=0, y=150)
b5 = Button(topper, height='114', width='115', image=b5_img, command=lambda: btn_click(b5))
b5.place(x=150, y=150)
b6 = Button(topper, height='114', width='115', image=b6_img, command=lambda: btn_click(b6))
b6.place(x=300, y=150)
b1 = Button(topper, height='114', width='115', image=b1_img, command=lambda: btn_click(b1))
b1.place(x=0, y=300)
b2 = Button(topper, height='114', width='115', image=b2_img, command=lambda: btn_click(b2))
b2.place(x=150, y=300)
b3 = Button(topper, height='114', width='115', image=b3_img, command=lambda: btn_click(b3))
b3.place(x=300, y=300)
  1. You need to use button.config(image=...) to change image option instead of button(image=...) inside btn_click() function.

  2. You assigned wrong value to player_turn (assign True when it is already True, False when it is already False).

Updated btn_click() function:

def btn_click(button):
    global player_turn
    if player_turn:
        button.config(image=bO_img)
    else:
        button.config(image=bX_img)
    player_turn = not player_turn

I think the button should be disabled after it is clicked so that it cannot be clicked again.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...