繁体   English   中英

Python | 如何使用 Tkinter 进行快速反应测试?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM