Tkinter и Python — ошибка типа переменной и как перезаписать строки — тест времени реакции

У меня есть тест реакции, работающий в консоли, но мне было любопытно сделать из него настольное приложение, поэтому я решил проверить Tkinter, но у меня есть некоторые проблемы с преобразованием и функциональностью. Во-первых, для обратного отсчета Tkinter может перезаписывать строки для создания эффекта обратного отсчета (3,2,1,GO). Во-вторых, я не уверен, как сделать переменную «начало» плавающей, чтобы ее можно было вычесть, чтобы получить значение для переменной «истекшее время». Я чувствую, что я действительно близко. Просто чего-то не хватает.

from tkinter import*
from tkinter import ttk
import time, random

root = Tk()

content = ttk.Frame(root, padding=(3,3,12,12), width=500, height=100)

def callback():
    elapsed = time.time()- start
    print(elapsed)
    result.set(elapsed)

result = StringVar()

def countdown():    
    time.sleep(random.randint(2,6))
    d = '!__GO__!'
    cd.set(d)
    start = time.time()
    start.set(start)

start = StringVar()
cd = StringVar()

ttk.Button(content, text="Start", command=countdown).grid(column=1, row=1, sticky=NW)
ttk.Label(content, text="Click on GO!").grid(column=2, row=1, sticky=N)
ttk.Button(content, text="Go", command = callback).grid(column=2, row=2, sticky=N)
ttk.Label(content, text="Result is: ").grid(column=2, row=3, sticky=(E,W))
ttk.Label(content, textvariable=cd).grid(column=2, row=4, sticky=S)
ttk.Label(content, textvariable=result).grid(column=3, row=3, sticky=S)

Я бы хотел, чтобы обратный отсчет отображал 3, затем 2, чтобы перезаписать его, затем 1, затем GO. А затем для отображения прошедшего времени с момента нажатия кнопки «Пуск» и нажатия кнопки «Перейти» (т.е. истекшее = время.время () - начало)


person KissMyAxe    schedule 11.07.2019    source источник


Ответы (1)


time.sleep заблокирует ваш основной поток, так что ваша программа зависнет на время time.sleep. Вам нужно либо thread свою функцию, либо использовать метод after, доступный для tkinter, который позволяет вам запускать обратный вызов через определенное время.

from tkinter import *
from tkinter import ttk
from datetime import datetime
import random

root = Tk()

content = ttk.Frame(root, padding=(3,3,12,12), width=500, height=100)
content.pack()

def callback():
    global start_time
    elapsed = datetime.now() - start_time
    result.set(elapsed)

result = StringVar()

def start(): #generates random countdown timer
    t = random.randint(2,6)
    def countdown(num): #function to provide countdown effect
        start_var.set(num)
        if num >=1:
            num -= 1
            root.after(1000,lambda: countdown(num)) #call itself again until countdown reaches 0
        else:
            start_var.set("GO!")
            global start_time
            start_time = datetime.now()
    countdown(t)

start_var = StringVar()

ttk.Button(content, text="Start", command=start).grid(column=1, row=1, sticky=NW)
ttk.Label(content, text="Click on GO!").grid(column=2, row=1, sticky=N)
ttk.Button(content, text="Go", command=callback).grid(column=2, row=2, sticky=N)
ttk.Label(content, text="Result is: ").grid(column=2, row=3, sticky=(E,W))
ttk.Label(content, textvariable=start_var).grid(column=2, row=4, sticky=S)
ttk.Label(content, textvariable=result).grid(column=3, row=3, sticky=S)

root.mainloop()
person Henry Yik    schedule 11.07.2019
comment
Великолепно! Спасибо за информацию. Я все еще очень новичок в tkinter, поэтому не знаю этих методов. Я хотел, чтобы GO появлялся в случайное время после 1, вместо того, чтобы обратный отсчет был случайным временем. Так что, надеюсь, метод after сделает то, что мне нужно. - person KissMyAxe; 11.07.2019