Я пытался создать тестер быстрой реакции с помощью модуля Tkinter в Python, но когда я нажимал кнопку Start
, окно просто зависало. И я не знаю, как восстановить это
Вот мой код:
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()
На самом деле, спасибо, если вы мне помогли :)
Вылетело и не могу найти в чем проблема
Затем сократите код до минимума, воспроизводящего сбой.
Ваша ошибка в том, что вы просите свою программу войти в бесконечный цикл при нажатии кнопки «Пуск». Интерпретатор никогда не выходит из этого цикла, и, таким образом, пользовательский интерфейс застревает, не имея возможности обновить себя или получить ввод, потому что интерпретатор все еще застрял в вашем цикле.
Так что вам нужно иметь другой подход для этого. Подобные проблемы обычно обрабатываются путем открытия отдельных потоков в вашей программе, которые могут выполняться независимо, так что на ваш основной поток, отвечающий за обновление окна пользовательского интерфейса, не влияет дочерний поток, выполняющий ваш бесконечный цикл. Затем основной поток может в какой-то момент отправить сообщение дочернему потоку о том, что цикл должен быть отменен, когда пользователь нажимает кнопку остановки.
Обработка этого в tkinter была упрощена с помощью метода after()
, который просто создает такой бесконечный цикл в отдельном потоке, чтобы основной поток продолжал работать. Ниже я привел небольшой пример того, как может выглядеть такой цикл after, и вы можете попробовать реализовать его в своем собственном коде. Если у вас все еще есть проблемы, откройте новый вопрос с большей ясностью.
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()
«Я не знаю, в чем здесь проблема». Мы тоже не знаем, поскольку вы не опубликовали ни сообщения об ошибке, ни трассировки стека.