首页 > 解决方案 > 我有一个问题,我无法在 tkinter 中设置带有条件的按钮

问题描述

from tkinter import *
import random
            
def click(buttons):
    global click
    global player_score
    global cpu_score
    global win
    global btn_list
    global turn
    click = random.choice(btn_list)
    while turn < 10 and not win:
        if buttons['text'] == ' ' and click == False :
            buttons.configure(text='O',fg='yellow')
            buttons.configure(state=DISABLED)
            click = True
        else:
            buttons = random.choice(btn_list)
            buttons.configure(text='X',fg='green')
            buttons.configure(state=DISABLED)
            click = False
    
    if (btn1['text'] == 'O' and btn2['text'] == 'O' and btn3['text'] == 'O' or
        btn4['text'] == 'O' and btn5['text'] == 'O' and btn6['text'] == 'O' or
        btn7['text'] == 'O' and btn8['text'] == 'O' and btn9['text'] == 'O' or
        btn1['text'] == 'O' and btn5['text'] == 'O' and btn9['text'] == 'O' or
        btn3['text'] == 'O' and btn5['text'] == 'O' and btn7['text'] == 'O' or
        btn1['text'] == 'O' and btn4['text'] == 'O' and btn7['text'] == 'O' or
        btn2['text'] == 'O' and btn5['text'] == 'O' and btn8['text'] == 'O' or
        btn3['text'] == 'O' and btn6['text'] == 'O' and btn9['text'] == 'O'):
            player_score += 1
            win = True
    elif (btn1['text'] == 'X' and btn2['text'] == 'X' and btn3['text'] == 'X' or
        btn4['text'] == 'X' and btn5['text'] == 'X' and btn6['text'] == 'X' or
        btn7['text'] == 'X' and btn8['text'] == 'X' and btn9['text'] == 'X' or
        btn1['text'] == 'X' and btn5['text'] == 'X' and btn9['text'] == 'X' or
        btn3['text'] == 'X' and btn5['text'] == 'X' and btn7['text'] == 'X' or
        btn1['text'] == 'X' and btn4['text'] == 'X' and btn7['text'] == 'X' or
        btn2['text'] == 'X' and btn5['text'] == 'X' and btn8['text'] == 'X' or
        btn3['text'] == 'X' and btn6['text'] == 'X' and btn9['text'] == 'X'):
            cpu_score += 1
            win = True



window = Tk()
window.title('Tic Tac Toe')


buttons = StringVar()

btn1 = Button(window,text=' ',bg='red',height=4,width=8,command=lambda:click(btn1))
btn1.grid(row=1,column=0)

btn2 = Button(window,text=' ',bg='blue',height=4,width=8,command=lambda:click(btn2))
btn2.grid(row=1,column=1)

btn3 = Button(window,text=' ',bg='red',height=4,width=8,command=lambda:click(btn3))
btn3.grid(row=1,column=2)

btn4 = Button(window,text=' ',bg='blue',height=4,width=8,command=lambda:click(btn4))
btn4.grid(row=2,column=0)

btn5 = Button(window,text=' ',bg='red',height=4,width=8,command=lambda:click(btn5))
btn5.grid(row=2,column=1)

btn6 = Button(window,text=' ',bg='blue',height=4,width=8,command=lambda:click(btn6))
btn6.grid(row=2,column=2)

btn7 = Button(window,text=' ',bg='red',height=4,width=8,command=lambda:click(btn7))
btn7.grid(row=3,column=0)

btn8 = Button(window,text=' ',bg='blue',height=4,width=8,command=lambda:click(btn8))
btn8.grid(row=3,column=1)

btn9 = Button(window,text=' ',bg='red',height=4,width=8,command=lambda:click(btn9))
btn9.grid(row=3,column=2)

btn_list = [btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9]

player_score = 0
cpu_score = 0
turn = 1
click = False
win = False

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "E:/Python/Python Projects Fun/tic-tac-toe_gui.py", line 73, in <lambda>
    btn8 = Button(window,text=' ',bg='blue',height=4,width=8,command=lambda:click(btn8))
TypeError: 'bool' object is not callable

当我运行并单击任何一个按钮时,就会出现错误消息。我想将一个玩家设置为计算机,它会点击随机按钮然后改变玩家的回合,请问我该如何写才能产生这种效果?另外我想问一下我们什么时候应该在函数中使用 lambda?

标签: pythonuser-interfacetkinter

解决方案


你需要一个部分。部分是部分 lambda。我曾尝试阅读有关 lambda 的内容,但没有一个完全卡住。我认为它的方式是 lambda 是实时的。如果我需要将变量传递给回调,我会使用 lambda 来声明我需要一个生活(不断变化的变量)。在这种情况下,您需要一个实时函数,但每个按钮都有一个静态变量,因此您需要一个局部变量。在下面的代码中,每次按 btn1 时,单击函数中的所有全局变量都会随程序发生变化,它将向单击函数发送零,btn2 发送一,依此类推。我继续并更正了您的回调功能和使用 .after 方法调用自身的机器人函数。1000 是以毫秒为单位的时间,因此您可以进行相应调整。

from tkinter import *
from functools import partial
import random


def click(button_num):
    global player_score
    global cpu_score
    global win
    global btn_list
    global turn
    global player
    button = btn_list[button_num]

    if button['text'] == ' ':
        button.configure(text='O', fg='yellow')
        button.configure(state=DISABLED)
        player = not player


def robot():
    global window
    global player_score
    global cpu_score
    global win
    global player
    if not player:
        button = random.choice(btn_list)
        if button['text'] == " ":
            button.configure(text='X', fg='green')
            button.configure(state=DISABLED)
            player = not player

    if (btn1['text'] == 'O' and btn2['text'] == 'O' and btn3['text'] == 'O' or
            btn4['text'] == 'O' and btn5['text'] == 'O' and btn6['text'] == 'O' or
            btn7['text'] == 'O' and btn8['text'] == 'O' and btn9['text'] == 'O' or
            btn1['text'] == 'O' and btn5['text'] == 'O' and btn9['text'] == 'O' or
            btn3['text'] == 'O' and btn5['text'] == 'O' and btn7['text'] == 'O' or
            btn1['text'] == 'O' and btn4['text'] == 'O' and btn7['text'] == 'O' or
            btn2['text'] == 'O' and btn5['text'] == 'O' and btn8['text'] == 'O' or
            btn3['text'] == 'O' and btn6['text'] == 'O' and btn9['text'] == 'O'):
        player_score += 1
        win = True
    elif (btn1['text'] == 'X' and btn2['text'] == 'X' and btn3['text'] == 'X' or
          btn4['text'] == 'X' and btn5['text'] == 'X' and btn6['text'] == 'X' or
          btn7['text'] == 'X' and btn8['text'] == 'X' and btn9['text'] == 'X' or
          btn1['text'] == 'X' and btn5['text'] == 'X' and btn9['text'] == 'X' or
          btn3['text'] == 'X' and btn5['text'] == 'X' and btn7['text'] == 'X' or
          btn1['text'] == 'X' and btn4['text'] == 'X' and btn7['text'] == 'X' or
          btn2['text'] == 'X' and btn5['text'] == 'X' and btn8['text'] == 'X' or
          btn3['text'] == 'X' and btn6['text'] == 'X' and btn9['text'] == 'X'):
        cpu_score += 1
        win = True
    window.after(1000, robot)


window = Tk()
window.title('Tic Tac Toe')

buttons = StringVar()

btn1 = Button(window, text=' ', bg='red', height=4, width=8, command=partial(click, 0))
btn1.grid(row=1, column=0)

btn2 = Button(window, text=' ', bg='blue', height=4, width=8, command=partial(click, 1))
btn2.grid(row=1, column=1)

btn3 = Button(window, text=' ', bg='red', height=4, width=8, command=partial(click, 2))
btn3.grid(row=1, column=2)

btn4 = Button(window, text=' ', bg='blue', height=4, width=8, command=partial(click, 3))
btn4.grid(row=2, column=0)

btn5 = Button(window, text=' ', bg='red', height=4, width=8, command=partial(click, 4))
btn5.grid(row=2, column=1)

btn6 = Button(window, text=' ', bg='blue', height=4, width=8, command=partial(click, 5))
btn6.grid(row=2, column=2)

btn7 = Button(window, text=' ', bg='red', height=4, width=8, command=partial(click, 6))
btn7.grid(row=3, column=0)

btn8 = Button(window, text=' ', bg='blue', height=4, width=8, command=partial(click, 7))
btn8.grid(row=3, column=1)

btn9 = Button(window, text=' ', bg='red', height=4, width=8, command=partial(click, 8))
btn9.grid(row=3, column=2)

btn_list = [btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9]

player = True
player_score = 0
cpu_score = 0
turn = 1
click = False
win = False

robot()
window.mainloop()

推荐阅读