首页 > 解决方案 > 开始按钮在我的 tkinter 程序中不起作用

问题描述

在这个练习程序中,我创建了一个彩色游戏。在此我创建了一个名为 Start Game 的按钮。只有在我按下开始游戏按钮后,游戏才会开始。游戏开始时此按钮也会消失。它第一次完美运行。但是当倒计时结束或玩家输了时,开始游戏按钮应该重新出现在同一位置。开始按钮再次出现,但它正在调用应有的函数。请有人帮忙吗?

from tkinter import *
from random import *

doc = open("Highscore.txt", "r")
us = 0
hs = int(doc.read())
time_count = 5
colorlist = ["Red", "Yellow", "Blue", "Green", "Orange", "Purple"]

def add_uscore():
    global us
    us+= 1
    score.config(text=(f"Score: {us}"))


def add_highscore():
    global us
    global hs
    if us>hs:
        hs = us
        highscore.config(text=(f"Highscore: {hs}"))
        doc2 = open("Highscore.txt","w")
        doc2.write(str(hs))
        doc2.close()


def start_game():
    global colorlist
    global textcolor
    rancolor = choice(colorlist)
    textcolor = choice(colorlist)
    start_btn.grid_forget()
    color.config(text=rancolor, fg=textcolor)
    btn1.config(state=ACTIVE, bg="Indian Red")
    btn2.config(state=ACTIVE, bg="Gold")
    btn3.config(state=ACTIVE, bg="DodgerBlue3")
    btn4.config(state=ACTIVE, bg="Sea Green")
    btn5.config(state=ACTIVE, bg="Dark Orange")
    btn6.config(state=ACTIVE, bg="Purple3")
    timer.grid(row=4, column=0, columnspan=3)


def countdown():
    global time_count
    if time_count > 0:
        time_count -= 1
        timer.config(text=(f"Countdown: {time_count}"))
        timer.after(1000, countdown)
    elif time_count==0:
        result.config(text="Time Over", fg="Indian Red")
        finish_game()


def finish_game():
    timer.grid_forget()
    start_btn.grid(row=4, column=0, columnspan=3)
    btn1.config(state=DISABLED)
    btn2.config(state=DISABLED)
    btn3.config(state=DISABLED)
    btn4.config(state=DISABLED)
    btn5.config(state=DISABLED)
    btn6.config(state=DISABLED)


def new_game():
    global us
    us = 0
    score.config(text=(f"Score: {us}"))
    finish_game()


def reset_game():
    global hs
    hs = 0
    doc2 = open("Highscore.txt","w")
    doc2.write(str(hs))
    doc2.close()
    new_game()


def check(ucolor):
    global textcolor
    global time_count
    if textcolor==ucolor:
        result.config(text="Good", fg="Sea Green")
        add_uscore()
        add_highscore()
        start_game()
        time_count = 5
    else:
        result.config(text="You Lose", fg="Indian Red")
        finish_game()



win = Tk()
win.title("Color Game")

#MENU
menu1 = Menu(win)
win.config(menu=menu1)

options = Menu(menu1)
menu1.add_cascade(label="Option", menu=options)
options.add_command(label="New Game", command=new_game)
options.add_command(label="Reset Game", command=reset_game)
options.add_command(label="Exit Game", command=quit)


#DISPLAY
color = Label(win, text="", font=("Comic Sans", 50), anchor=W)
color.grid(row=0, column=0, columnspan=4)

#BUTTON

btn1 = Button(win, text="Red", height=10, width=10, state=DISABLED, command=lambda:check("Red"))
btn1.grid(row=1, column=0)

btn2 = Button(win, text="Yellow", height=10, width=10,state=DISABLED, command=lambda:check("Yellow"))
btn2.grid(row=1, column=1)

btn3 = Button(win, text="Blue", height=10, width=10, state=DISABLED, command=lambda:check("Blue"))
btn3.grid(row=1, column=2)

btn4 = Button(win, text="Green", height=10, width=10, state=DISABLED, command=lambda:check("Green"))
btn4.grid(row=2, column=0)

btn5 = Button(win, text="Orange", height=10, width=10, state=DISABLED, command=lambda:check("Orange"))
btn5.grid(row=2, column=1)

btn6 = Button(win, text="Purple", height=10, width=10, state=DISABLED, command=lambda:check("Purple"))
btn6.grid(row=2, column=2)

#RESULT
result = Label(win, text="", font=("Ariel", 25))
result.grid(row=3, column=0, columnspan=3)

#COUNTDOWN
timer = Label(win, text="", fg="Dark Orange", font=("Ariel", 15))

#START BUTTON
start_btn = Button(win, text="START GAME", bg="Green", command= lambda: [start_game(), countdown()])
start_btn.grid(row=4, column=0, columnspan=3)

#SCORE
score = Label(win, text=(f"Score: {us}"), fg="Sea Green", font=("Ariel", 10))
score.grid(row=5, column=0, columnspan=3)

#HIGHSCORE
highscore = Label(win, text=(f"Highscore: {hs}"), font=("Ariel", 10), fg="firebrick4")
highscore.grid(row=6, column=0, columnspan=3)

win.mainloop()

标签: pythontkinter

解决方案


在您的代码中有一个变量time_count

在代码开头设置为5

...
hs = int(doc.read())
time_count = 5 # <-----------
colorlist = ["Red", "Yellow", "Blue", "Green", "Orange", "Purple"]
...

当你用完时间时,time_count它的值为0。当你再次调用该start_game函数时,它看到的time_count是0,所以游戏必须结束。要解决此问题,您必须time_count在每次游戏结束后重置。像这样的东西对我有用:

def finish_game():
    global time_sleep
    time_sleep = 5
    timer.grid_forget()
    start_btn.grid(row=4, column=0, columnspan=3)
    btn1.config(state=DISABLED)
    btn2.config(state=DISABLED)
    btn3.config(state=DISABLED)
    btn4.config(state=DISABLED)
    btn5.config(state=DISABLED)
    btn6.config(state=DISABLED)

编辑:

我设法通过添加一个变量来修复countdown在后台自行执行的函数。gameover游戏结束时设置为1,游戏开始时再次设置为0。倒计时功能检查gameover并仅在设置为 时执行0。我还让result标签只在游戏结束时出现。

完整代码:

from tkinter import *
from random import *

doc = open("Highscore.txt", "r")
us = 0
hs = int(doc.read())
time_count = 5
colorlist = ["Red", "Yellow", "Blue", "Green", "Orange", "Purple"]

def add_uscore():
    global us
    us+= 1
    score.config(text=(f"Score: {us}"))


def add_highscore():
    global us
    global hs
    if us>hs:
        hs = us
        highscore.config(text=(f"Highscore: {hs}"))
        doc2 = open("Highscore.txt","w")
        doc2.write(str(hs))
        doc2.close()


def start_game():
    global gameover
    global colorlist
    global textcolor
    gameover = 0
    rancolor = choice(colorlist)
    textcolor = choice(colorlist)
    start_btn.grid_forget()
    result.grid_forget()
    color.config(text=rancolor, fg=textcolor)
    btn1.config(state=ACTIVE, bg="Indian Red")
    btn2.config(state=ACTIVE, bg="Gold")
    btn3.config(state=ACTIVE, bg="DodgerBlue3")
    btn4.config(state=ACTIVE, bg="Sea Green")
    btn5.config(state=ACTIVE, bg="Dark Orange")
    btn6.config(state=ACTIVE, bg="Purple3")
    timer.grid(row=4, column=0, columnspan=3)


def countdown():
    global time_count
    if time_count > 0 and gameover != 1:
        time_count -= 1
        timer.config(text=(f"Countdown: {time_count}"))
        timer.after(1000, countdown)
    elif time_count==0:
        result.config(text="Time Over", fg="Indian Red")
        finish_game()


def finish_game():
    global time_count
    time_count = 5
    timer.grid_forget()
    result.grid(row=3, column=0, columnspan=3)
    start_btn.grid(row=4, column=0, columnspan=3)
    btn1.config(state=DISABLED)
    btn2.config(state=DISABLED)
    btn3.config(state=DISABLED)
    btn4.config(state=DISABLED)
    btn5.config(state=DISABLED)
    btn6.config(state=DISABLED)


def new_game():
    global us
    us = 0
    score.config(text=(f"Score: {us}"))
    finish_game()


def reset_game():
    global hs
    hs = 0
    doc2 = open("Highscore.txt","w")
    doc2.write(str(hs))
    doc2.close()
    new_game()


def check(ucolor):
    global textcolor
    global time_count
    global gameover
    if textcolor==ucolor:
        result.config(text="Good", fg="Sea Green")
        add_uscore()
        add_highscore()
        start_game()
        time_count = 5
    else:
        result.config(text="You Lose", fg="Indian Red")
        gameover = 1
        finish_game()



win = Tk()
win.title("Color Game")

#MENU
menu1 = Menu(win)
win.config(menu=menu1)

options = Menu(menu1)
menu1.add_cascade(label="Option", menu=options)
options.add_command(label="New Game", command=new_game)
options.add_command(label="Reset Game", command=reset_game)
options.add_command(label="Exit Game", command=quit)


#DISPLAY
color = Label(win, text="", font=("Comic Sans", 50), anchor=W)
color.grid(row=0, column=0, columnspan=4)

#BUTTON

btn1 = Button(win, text="Red", height=10, width=10, state=DISABLED, command=lambda:check("Red"))
btn1.grid(row=1, column=0)

btn2 = Button(win, text="Yellow", height=10, width=10,state=DISABLED, command=lambda:check("Yellow"))
btn2.grid(row=1, column=1)

btn3 = Button(win, text="Blue", height=10, width=10, state=DISABLED, command=lambda:check("Blue"))
btn3.grid(row=1, column=2)

btn4 = Button(win, text="Green", height=10, width=10, state=DISABLED, command=lambda:check("Green"))
btn4.grid(row=2, column=0)

btn5 = Button(win, text="Orange", height=10, width=10, state=DISABLED, command=lambda:check("Orange"))
btn5.grid(row=2, column=1)

btn6 = Button(win, text="Purple", height=10, width=10, state=DISABLED, command=lambda:check("Purple"))
btn6.grid(row=2, column=2)

#RESULT
result = Label(win, text="", font=("Ariel", 25))

#COUNTDOWN
timer = Label(win, text="", fg="Dark Orange", font=("Ariel", 15))

#START BUTTON
start_btn = Button(win, text="START GAME", bg="Green", command= lambda: [start_game(), countdown()])
start_btn.grid(row=4, column=0, columnspan=3)

#SCORE
score = Label(win, text=(f"Score: {us}"), fg="Sea Green", font=("Ariel", 10))
score.grid(row=5, column=0, columnspan=3)

#HIGHSCORE
highscore = Label(win, text=(f"Highscore: {hs}"), font=("Ariel", 10), fg="firebrick4")
highscore.grid(row=6, column=0, columnspan=3)

win.mainloop()

请注意result标签如何仅在游戏结束时放置在网格管理器中,并且在游戏再次开始时将其移除:

游戏结束时放置result标签.grid

def finish_game():
    ...
    result.grid(row=3, column=0, columnspan=3)
    ...

游戏开始时移除result标签.grid_forget

def start_game():
    ...
    result.grid_forget()
    ...

推荐阅读