英文:
Why does the timer in this level go faster each time a new image is shown in tkinter?
问题
这是您的代码的中文翻译部分:
def medium_level():
global score2,current_image2, total_games,total_w
total_games+= 1
current_image2 =0
score2 = 0
new = Toplevel(window)
new.title("Medium Mode")
new.configure(background=bg2)
new.geometry("600x500")
ans=tk.Entry(new,font=('Times', 25))
ans["justify"] = "center"
ans["borderwidth"] = "1px"
ans.place(x=90,y=270,width=414,height=188)
rules2=tk.Label(new, font=('Times', 20),bg=bg2)
rules2["text"] = "Enter Country Name Here:"
rules2["justify"] = "center"
rules2.place(x=110,y=230)
timelbl=tk.Label(new, text="Time: ",font=('Times', 15),bg=bg2)
timelbl.place(x=480,y=50)
score_label = tk.Label(new, text="Score: 0"+"/12", font=('Times', 15),bg=bg2)
score_label.place(x=40, y=50)
image_label = tk.Label(master=new)
image_label.place(relx=0.30, rely=0.10)
image_files = ['bangladesh.png', 'germany.png', 'turkey.png', 'egypt.png', 'madagascar.png','ecuador.png','croatia.png','palestine.png','south africa.png','mongolia.png','peru.png','vietnam.png']
random.shuffle(image_files)
def next_image2():
global current_image2, countdown
if current_image2 < len(image_files):
# 获取下一张图像并显示
image_path = image_files[current_image2]
image = tk.PhotoImage(file=image_path)
image_label.configure(image=image)
image_label.image = image
current_image2 += 1
countdown = 20
start_timer()
timelbl.config(text=f"Time: {countdown}")
else:
# 显示最终得分
messagebox.showinfo("Game Over", f"Your score is: {score2}"+"/12")
new.quit()
def start_timer():
global countdown
countdown = 20
update_timer()
def update_timer():
global countdown
timelbl.config(text=f"Time: {countdown}")
if countdown == 0:
# 时间到,移动到下一张图像
next_image2()
else:
countdown -= 1
new.after(1000, update_timer)
def check_answer2(event):
global score2,total_w,countdown,update_timer
# 从输入框获取用户答案
user_answer = ans.get().strip().lower()
# 获取当前图像的正确答案
correct_answer = image_files[current_image2 - 1].split('.')[0].lower()
# 检查用户答案是否正确
if user_answer == correct_answer:
score2 += 1
total_w+=1
score_label.config(text=f"Score: {score2}"+"/12")
# 清空输入框
ans.delete(0, tk.END)
# 移动到下一张图像
next_image2()
# 将check_answer函数绑定到回车键按下事件
ans.bind('<Return>', check_answer2)
next_image2()
这是您尝试的一种方式:
def start_timer():
global countdown
countdown = 20
update_timer()
def update_timer():
global countdown
timelbl.config(text=f"Time: {countdown}")
if countdown == 0:
# 时间到,移动到下一张图像
next_image2()
else:
countdown -= 1
new.after(1000, update_timer)
但是,无论我尝试了什么,计时器的速度似乎只会变得更快。
如果您的计时器速度越来越快,可能是因为您的计时器在每次显示新图像时都会被重置,但您的 update_timer
函数也在每次新图像显示时被调用。这意味着您的计时器会以更高的速度递减,因为它实际上在进行多次计数。
为了解决这个问题,您可以尝试将 update_timer
函数的调用移到 start_timer
函数内部,以确保在每次新图像显示时只启动一个计时器。这应该防止计时器速度越来越快的问题。
例如:
def start_timer():
global countdown
countdown = 20
update_timer()
def update_timer():
global countdown
timelbl.config(text=f"Time: {countdown}")
if countdown == 0:
# 时间到,移动到下一张图像
next_image2()
else:
countdown -= 1
new.after(1000, update_timer)
# 在next_image2函数内部调用start_timer来启动计时器
def next_image2():
global current_image2, countdown
if current_image2 < len(image_files):
# 获取下一张图像并显示
image_path = image_files[current_image2]
image = tk.PhotoImage(file=image_path)
image_label.configure(image=image)
image_label.image = image
current_image2 += 1
countdown = 20
start_timer()
timelbl.config(text=f"Time: {countdown}")
else:
# 显示最终得分
messagebox.showinfo("Game Over", f"Your score is: {score2}"+"/12")
new.quit()
这样,每次新图像显示时,都会启动一个新的计时器,并且计时器速度不会越来越快。
英文:
For my game, when a new flag is shown each time after the user clicks enter or the timer goes to zero, the timer is supposed to reset back to 20 which it does but, it goes down even faster each time the new image is shown. How do I make it so that it goes down only 1 second each time and doesn't get faster?
Here is the code to the full level:
def medium_level():
global score2,current_image2, total_games,total_w
total_games+= 1
current_image2 =0
score2 = 0
new = Toplevel(window)
new.title("Medium Mode")
new.configure(background=bg2)
new.geometry("600x500")
ans=tk.Entry(new,font=('Times', 25))
ans["justify"] = "center"
ans["borderwidth"] = "1px"
ans.place(x=90,y=270,width=414,height=188)
rules2=tk.Label(new, font=('Times', 20),bg=bg2)
rules2["text"] = "Enter Country Name Here:"
rules2["justify"] = "center"
rules2.place(x=110,y=230)
timelbl=tk.Label(new, text="Time: ",font=('Times', 15),bg=bg2)
timelbl.place(x=480,y=50)
score_label = tk.Label(new, text="Score: 0"+"/12", font=('Times', 15),bg=bg2)
score_label.place(x=40, y=50)
image_label = tk.Label(master=new)
image_label.place(relx=0.30, rely=0.10)#, relheight=0.5, relwidth=0.5)
image_files = ['bangladesh.png', 'germany.png', 'turkey.png', 'egypt.png', 'madagascar.png','ecuador.png','croatia.png','palestine.png','south africa.png','mongolia.png','peru.png','vietnam.png']
random.shuffle(image_files)
def next_image2():
global current_image2, countdown
if current_image2 < len(image_files):
# Get the next image and display it
image_path = image_files[current_image2]
image = tk.PhotoImage(file=image_path)
image_label.configure(image=image)
image_label.image = image
current_image2 += 1
countdown = 20
start_timer()
timelbl.config(text=f"Time: {countdown}")
else:
# Show the final score
messagebox.showinfo("Game Over", f"Your score is: {score2}"+"/12")
new.quit()
def start_timer():
global countdown
countdown = 20
update_timer()
def update_timer():
global countdown
timelbl.config(text=f"Time: {countdown}")
if countdown == 0:
# Time's up, move to the next image
next_image2()
else:
countdown -= 1
new.after(1000, update_timer)
def check_answer2(event):
global score2,total_w,countdown,update_timer
# Get the user's answer from the entry box
user_answer = ans.get().strip().lower()
# Get the correct answer for the current image
correct_answer = image_files[current_image2 - 1].split('.')[0].lower()
# Check if the user's answer is correct
if user_answer == correct_answer:
score2 += 1
total_w+=1
score_label.config(text=f"Score: {score2}"+"/12")
# Clear the entry box
ans.delete(0, tk.END)
# Move to the next image
next_image2()
# Bind the check_answer function to the Return key press event
ans.bind('<Return>', check_answer2)
next_image2()
This is one of the ways I have tried:
def start_timer():
global countdown
countdown = 20
update_timer()
def update_timer():
global countdown
timelbl.config(text=f"Time: {countdown}")
if countdown == 0:
# Time's up, move to the next image
next_image2()
else:
countdown -= 1
new.after(1000, update_timer)
But, for every thing I try the speed of the timer just gets faster
答案1
得分: 1
这是因为在启动新的倒计时时,您没有取消现有的 countdown。
after_id = None # 初始化全局的 after ID
def medium_level():
...
def start_timer():
global countdown, after_id # .after() 返回的 ID
countdown = 20
# 如果存在 after ID,则取消现有的 after 循环
if after_id:
new.after_cancel(after_id)
after_id = None
update_timer()
def update_timer():
global countdown, after_id
timelbl.config(text=f"时间:{countdown}")
if countdown == 0:
# 时间到,转到下一张图片
next_image2()
else:
countdown -= 1
# 保存 after ID
after_id = new.after(1000, update_timer)
...
英文:
It is because you do not cancel the existing countdown when starting new countdown.
after_id = None # initialize the global after ID
def medium_level():
...
def start_timer():
global countdown, after_id # ID returned by .after()
countdown = 20
# cancel existing after loop if any
if after_id:
new.after_cancel(after_id)
after_id = None
update_timer()
def update_timer():
global countdown, after_id
timelbl.config(text=f"Time: {countdown}")
if countdown == 0:
# Time's up, move to the next image
next_image2()
else:
countdown -= 1
# save the after ID
after_id = new.after(1000, update_timer)
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论