有没有办法在 Python 中指定的时间后创建函数 运行 而无需 after 方法?
Is there a way to make a function run after a specified amount of time in Python without the after method?
我正在尝试创建一个简单的程序来跟踪用户在 Tkinter 中的每秒点击次数,但我不知道如何使用 after 方法让程序等待而不冻结程序。问题是我需要在时间结束后记录高分,但是使用这种方法,分数会在点击计数器上升之前记录下来。这是我的代码:
from tkinter import *
import time
root = Tk()
root.geometry('600x410')
screen = Canvas(root)
h = 6 #button height
w = 12 #button width
c = 0 #counts amount of times clicked
start_btn = 0 #logs clicks of the start button
high_score = 0 #logs the highest score
time = 0
def count_hs():
high_score = c
def remove_time():
global time
time -= 1
def countdown(n):
for i in range(n):
time = n
root.after(1000, remove_time())
#alternatively i tried this:
#time.sleep(1)
#remove_time()
if time <= 0:
b["text"] = "Test done."
break
def start_test():
global start_btn
b["text"] = "Click to begin."
start_btn += 1
print("start button: " + str(start_btn))
def button_click():
global start_btn
global c
c+=1
print("click counter: " + str(c))
#resets the amount of clicks on the large button when the start button is pressed
if c >= 1 and start_btn >= 1:
print("test1")
c = 1
start_btn = 0
if b["text"] == "Click to begin.":
print("test2")
b["text"] = "Click!"
countdown(6)
count_hs()
print("hs: " +str(high_score))
#primary button
b = Button(root, text=" ", font=("Arial", 40), height = h, width = w, command = lambda: button_click())
b.grid(row=0, column=0)
#start button
start = Button(root, text="Start.", command = lambda: start_test())
start.grid(row=0, column=1)
root.mainloop()
试一试
from tkinter import *
root = Tk()
root.geometry('600x410')
screen = Canvas(root)
h = 6 # button height
w = 12 # button width
c = 0 # counts amount of times clicked
start_btn = 0 # logs clicks of the start button
high_score = 0 # logs the highest score
time = 0
def count_hs():
global high_score
if c > high_score:
high_score = c
return high_score
def remove_time():
global time
time -= 1
if time > 0:
root.after(1000, remove_time)
else:
show_score()
def start_test():
global start_btn
global c
global time
b["text"] = "Click to begin."
start_btn += 1
print("start button: " + str(start_btn))
# Reset your timer and counter
time = 6
c = 0
def button_click(*args):
global start_btn
global c
# resets the amount of clicks on the large button when the start button is pressed
if c == 0 and start_btn >= 1:
start_btn = 0
b["text"] = "Click!"
root.after(1000, remove_time)
print("hs: " + str(high_score))
else:
c += 1
print("click counter: " + str(c))
def show_score():
global c
score_label.configure(text=str(c))
high_score_label.configure(text=str(count_hs()))
c = 0
b['text'] = ""
# primary button
b = Button(root, text="", font=("Arial", 40), height=h, width=w, command=button_click)
b.grid(row=0, column=0, rowspan=5)
# start button
start = Button(root, text="Start.", command=lambda: start_test())
start.grid(row=0, column=1)
Label(root, text="Your score").grid(row=1, column=1)
score_label = Label(root, text="")
score_label.grid(row=2, column=1)
Label(root, text="High score").grid(row=3, column=1)
high_score_label = Label(root, text="")
high_score_label.grid(row=4, column=1)
root.mainloop()
少量更改:
- 在
count_hs
中,我假设您只有在当前分数超过它时才会更新最高分。
- 您可以将
remove_time
用作计时器,使其在 time <= 0
之前自行调用,在这种情况下您应该结束游戏。
- 我使用
start
按钮作为重置器,因此当它被点击时它会重置 c
和 time
。
- 在
button_click
上,您现在只能费心更新 c
(并更改开头的文本)。
- 最后,我添加了一些标签来显示最终结果,包括当前分数和高分。
一些继续前进的建议:
- 您可以为应用程序创建一个 class 变量,而不是
global
个变量,它应该可以让您更轻松地交换信息并避免细微的错误。
- 您可以改进布局,尤其是新添加的标签。
- 您可以将您原来的计时器设置为参数(目前,它设置在
start_test
内)。
- 我建议您不要导入
from tkinter import *
,而是执行 import tkinter as tk
或 from tkinter import ...
之类的操作,因为它可以提高可读性并减少错误来源。
我正在尝试创建一个简单的程序来跟踪用户在 Tkinter 中的每秒点击次数,但我不知道如何使用 after 方法让程序等待而不冻结程序。问题是我需要在时间结束后记录高分,但是使用这种方法,分数会在点击计数器上升之前记录下来。这是我的代码:
from tkinter import *
import time
root = Tk()
root.geometry('600x410')
screen = Canvas(root)
h = 6 #button height
w = 12 #button width
c = 0 #counts amount of times clicked
start_btn = 0 #logs clicks of the start button
high_score = 0 #logs the highest score
time = 0
def count_hs():
high_score = c
def remove_time():
global time
time -= 1
def countdown(n):
for i in range(n):
time = n
root.after(1000, remove_time())
#alternatively i tried this:
#time.sleep(1)
#remove_time()
if time <= 0:
b["text"] = "Test done."
break
def start_test():
global start_btn
b["text"] = "Click to begin."
start_btn += 1
print("start button: " + str(start_btn))
def button_click():
global start_btn
global c
c+=1
print("click counter: " + str(c))
#resets the amount of clicks on the large button when the start button is pressed
if c >= 1 and start_btn >= 1:
print("test1")
c = 1
start_btn = 0
if b["text"] == "Click to begin.":
print("test2")
b["text"] = "Click!"
countdown(6)
count_hs()
print("hs: " +str(high_score))
#primary button
b = Button(root, text=" ", font=("Arial", 40), height = h, width = w, command = lambda: button_click())
b.grid(row=0, column=0)
#start button
start = Button(root, text="Start.", command = lambda: start_test())
start.grid(row=0, column=1)
root.mainloop()
试一试
from tkinter import *
root = Tk()
root.geometry('600x410')
screen = Canvas(root)
h = 6 # button height
w = 12 # button width
c = 0 # counts amount of times clicked
start_btn = 0 # logs clicks of the start button
high_score = 0 # logs the highest score
time = 0
def count_hs():
global high_score
if c > high_score:
high_score = c
return high_score
def remove_time():
global time
time -= 1
if time > 0:
root.after(1000, remove_time)
else:
show_score()
def start_test():
global start_btn
global c
global time
b["text"] = "Click to begin."
start_btn += 1
print("start button: " + str(start_btn))
# Reset your timer and counter
time = 6
c = 0
def button_click(*args):
global start_btn
global c
# resets the amount of clicks on the large button when the start button is pressed
if c == 0 and start_btn >= 1:
start_btn = 0
b["text"] = "Click!"
root.after(1000, remove_time)
print("hs: " + str(high_score))
else:
c += 1
print("click counter: " + str(c))
def show_score():
global c
score_label.configure(text=str(c))
high_score_label.configure(text=str(count_hs()))
c = 0
b['text'] = ""
# primary button
b = Button(root, text="", font=("Arial", 40), height=h, width=w, command=button_click)
b.grid(row=0, column=0, rowspan=5)
# start button
start = Button(root, text="Start.", command=lambda: start_test())
start.grid(row=0, column=1)
Label(root, text="Your score").grid(row=1, column=1)
score_label = Label(root, text="")
score_label.grid(row=2, column=1)
Label(root, text="High score").grid(row=3, column=1)
high_score_label = Label(root, text="")
high_score_label.grid(row=4, column=1)
root.mainloop()
少量更改:
- 在
count_hs
中,我假设您只有在当前分数超过它时才会更新最高分。 - 您可以将
remove_time
用作计时器,使其在time <= 0
之前自行调用,在这种情况下您应该结束游戏。 - 我使用
start
按钮作为重置器,因此当它被点击时它会重置c
和time
。 - 在
button_click
上,您现在只能费心更新c
(并更改开头的文本)。 - 最后,我添加了一些标签来显示最终结果,包括当前分数和高分。
一些继续前进的建议:
- 您可以为应用程序创建一个 class 变量,而不是
global
个变量,它应该可以让您更轻松地交换信息并避免细微的错误。 - 您可以改进布局,尤其是新添加的标签。
- 您可以将您原来的计时器设置为参数(目前,它设置在
start_test
内)。 - 我建议您不要导入
from tkinter import *
,而是执行import tkinter as tk
或from tkinter import ...
之类的操作,因为它可以提高可读性并减少错误来源。