![](/img/trans.png)
[英]Tkinter and Python - variable type error and how to overwrite strings - Reaction Time Test
[英]Python | How do i make a Fast Reaction test with Tkinter?
我尝试使用 Python 中的 Tkinter 模块制作快速反应测试仪,但是当我单击“ Start
”按钮时,它只会冻结 window。 而且我不知道如何恢复
这是我的代码:
import webbrowser as wb
import time
import math
from random import *
from tkinter import *
from PIL import ImageTk, Image
seconds = 0
miliseconds = 0
minutes = 0
def reactionStarted():
global seconds, miliseconds, greenimages, redimages, minutes
# Put Image Green
reactionImage.config(image=greenimages)
# Random Countdown
countdownSecond = randint(4, 9)
countdownMiliSecond = randint(0, 9)
# Turn into float ( More Randomized )
countdownBonk = float(str(countdownSecond) + "." + str(countdownMiliSecond))
# Start Countdown
print(countdownBonk) # i was testing if this was the problem but its not
time.sleep(countdownBonk)
# Red image ( fast reaction part )
reactionImage.config(image=redimages)
# Timer
timeLoop = True
while timeLoop:
miliseconds += 1
time.sleep(0.1)
if miliseconds == 10:
seconds += 1
miliseconds = 0
elif seconds == 60:
seconds = 0
minutes += 1
def reactionCompleted():
global seconds, miliseconds, minutes
timeLoop = False
if not timeLoop:
reactionImage.config(image='', text=(
str(minutes) + "Minute(s)" + str(seconds) + "Second(s)" + str(miliseconds) + "Milisecond(s)"))
root = Tk()
root.title("Fast Reaction Test")
greenimages = ImageTk.PhotoImage(Image.open("green.png"))
redimages = ImageTk.PhotoImage(Image.open("red.png"))
reactionImage = Label(text='Click the button Below To Start!')
reactionImage.pack()
Start = Button(root, width=500, height=5, text="Click Here to Start", command=reactionStarted)
Start.pack()
Stop = Button(root, width=500, height=10, text="Stop (Spacebar)", command=reactionCompleted)
Stop.bind("<space>", reactionCompleted)
Stop.focus_force()
Stop.pack()
root.mainloop()
真的,谢谢你帮助我:)
您的错误是您在单击开始按钮时要求程序进入无限循环。 解释器永远不会离开该循环,因此 UI 会卡住而无法更新自身或接收输入,因为解释器仍然卡在您的循环中。
因此,您需要为此采用另一种方法。 此类问题通常通过在程序中打开单独的线程来处理,这些线程可以独立执行,以便负责更新 UI window 的主线程不受运行无限循环的子线程的影响。 然后,当用户按下停止按钮时,主线程可以在某个时候向子线程发送一条消息,表明循环应该被取消。
使用after()
方法在 tkinter 中处理这个问题变得很容易,它只是在单独的线程中创建这样一个无限循环以允许主线程继续运行。 我在下面包含了一个小例子,说明了这种后循环的外观,您可以尝试在自己的代码中实现它。 如果您仍有问题,请打开一个更清晰的新问题。
import tkinter as tk
import time
class Timer:
def __init__(self):
self.root = tk.Tk()
self.sv = tk.StringVar()
self.start_time = None
self.after_loop = None
self.make_widgets()
self.root.mainloop()
def make_widgets(self):
tk.Label(self.root, textvariable=self.sv).pack()
tk.Button(self.root, text='start', command=self.start).pack()
tk.Button(self.root, text='stop', command=self.stop).pack()
def start(self):
self.start_time = time.time()
self.timer()
def timer(self):
self.sv.set(round(time.time() - self.start_time))
self.after_loop = self.root.after(500, self.timer)
def stop(self):
if self.after_loop is not None:
self.root.after_cancel(self.after_loop)
self.after_loop = None
Timer()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.