Таймер Python в математической игре Tkinter

avatar
SterlinkArcher
10 июля 2013 в 11:03
3431
5
4

Я хочу добавить таймер для своей простой математической игры. Пока все работает нормально, пользователь получает вопросы при нажатии кнопки и получает обратную связь по ответу. Я хочу добавить таймер, чтобы пользователь мог видеть, сколько времени требуется, чтобы ответить на умножение. Это последняя часть моего прототипа для этой математической игры. Я хочу, чтобы таймер запускался, когда пользователь нажимает «nytt tal», что означает новый номер на шведском языке, и останавливался, когда пользователь нажимает «svar», что означает ответ на шведском языке. Вот мой код.

from Tkinter import *
import tkMessageBox
import random
import time
import sys

# Definition for the question asked to user 
def fraga1():
    global num3 
    num3 = random.randint(1, 10)
    global num4 
    num4 = random.randint(1, 10)
    global svar1 
    svar1 = num3 * num4
    label1.config(text='Vad blir ' + str(num3) + '*' + str(num4) + '?')
    entry1.focus_set()


#The answer giving feedback based on answer
def svar1():
   mainAnswer = entry1.get()
   if len(mainAnswer) == 0:
      tkMessageBox.showwarning(message='Skriv in några nummer!')
   return
   if int(mainAnswer) != svar1:
      tkMessageBox.showwarning(message='Tyvärr det rätta svaret: ' + str(svar1))
   else:
      tkMessageBox.showinfo(message='RÄTT!! :)')

#The quit button definition
def quit():
   global root
   root.destroy()

#Definition for the timer this part doesnt work
def start():
   global count_flag 
   fraga1()
   count_flag = True
   count = 0.0
   while True:
      if count_flag == False:
          break
   label['text'] = str(count)
   time.sleep(0.1)
   root.update()
   count += 0.1


#Window code
root = Tk()
root.title("multiplikations tidtagning")
root.geometry('800x500')

count_flag = True

# Welcome message in labels
label2 = Label(root, text="Hej!\n  Nu ska vi lösa lite matteproblem!")
label2.config(font=('times', 18, 'bold'), fg='black', bg='white')
label2.grid(row=0, column=0)

#Instructions how to play in labels

label3 = Label(root, text="Instruktioner!\n  För att starta ett spel tryck på nyttspel") 
label3.config(font=('times', 12, 'bold'), fg='black', bg='white')
label3.grid(row=2, column=2)

#other label
label1 = Label(root)
label1.grid(row=2, column=0)


# entry widget for the start button
entry1 = Entry(root)
entry1.grid(row=3, column=0)

# restart gives a new question
entry1.bind('', func=lambda e:checkAnswer())

#Buttons

fragaBtn = Button(root, text='Nytt tal', command=fraga1)
fragaBtn.grid(row=4, column=0)

svarButton = Button(root, text='Svar', command=svar1)
svarButton.grid(row=4, column=1)


quit_bttn = Button(root, text = "Avsluta", command=quit)
quit_bttn.grid(row=5, column=0)



root.mainloop()
Источник
Cid.C
9 мая 2016 в 01:57
0

Здравствуйте, посмотрите сюда => coderhelper.com/questions/36777643/how-to-stop-a-timer-python Надеюсь, это поможет :)

Ответы (5)

avatar
tusharmakkar08
10 июля 2013 в 12:44
7

Думаю, вам нужно вот это.

from Tkinter import *
import time

class StopWatch(Frame):  
    """ Implements a stop watch frame widget. """                                                                
    def __init__(self, parent=None, **kw):        
        Frame.__init__(self, parent, kw)
        self._start = 0.0        
        self._elapsedtime = 0.0
        self._running = 0
        self.timestr = StringVar()               
        self.makeWidgets()      

    def makeWidgets(self):                         
        """ Make the time label. """
        l = Label(self, textvariable=self.timestr)
        self._setTime(self._elapsedtime)
        l.pack(fill=X, expand=NO, pady=2, padx=2)                      

    def _update(self): 
        """ Update the label with elapsed time. """
        self._elapsedtime = time.time() - self._start
        self._setTime(self._elapsedtime)
        self._timer = self.after(50, self._update)

    def _setTime(self, elap):
        """ Set the time string to Minutes:Seconds:Hundreths """
        minutes = int(elap/60)
        seconds = int(elap - minutes*60.0)
        hseconds = int((elap - minutes*60.0 - seconds)*100)                
        self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))

    def Start(self):                                                     
        """ Start the stopwatch, ignore if running. """
        if not self._running:            
            self._start = time.time() - self._elapsedtime
            self._update()
            self._running = 1        

    def Stop(self):                                    
        """ Stop the stopwatch, ignore if stopped. """
        if self._running:
            self.after_cancel(self._timer)            
            self._elapsedtime = time.time() - self._start    
            self._setTime(self._elapsedtime)
            self._running = 0

    def Reset(self):                                  
        """ Reset the stopwatch. """
        self._start = time.time()         
        self._elapsedtime = 0.0    
        self._setTime(self._elapsedtime)


def main():
    root = Tk()
    sw = StopWatch(root)
    sw.pack(side=TOP)

    Button(root, text='Start', command=sw.Start).pack(side=LEFT)
    Button(root, text='Stop', command=sw.Stop).pack(side=LEFT)
    Button(root, text='Reset', command=sw.Reset).pack(side=LEFT)
    Button(root, text='Quit', command=root.quit).pack(side=LEFT)

    root.mainloop()

if __name__ == '__main__':
    main()

PS: Вставьте это в свой код, я только что реализовал базовый таймер в tkinter.

SterlinkArcher
10 июля 2013 в 12:52
0

Этот код, который вы разместили, должен соответствовать определению def start ()? Дата выхода в разделе импорта

tusharmakkar08
10 июля 2013 в 13:08
0

Да, вы можете запустить его, но тогда вместо while True вам нужно снова и снова вызывать функцию запуска ... для распечатки этикетки и ее обновления

SterlinkArcher
10 июля 2013 в 13:39
1

Я не могу понять ваш ответ, я пробовал то, что вы пишете, но почему-то мне это не подходит.

Ron Zhang
25 сентября 2018 в 09:19
1

@ tusharmakkar08 Я думаю, вам нужно объяснить, что именно вы добавили в свой код, чтобы программа работала лучше, вместо того, чтобы просто отвечать с помощью лучшего решения кода. Объяснения легко помогут вопрошающему понять, что происходит с вашим решением.

avatar
Gonzalez
28 июля 2021 в 15:01
0

хорошо, если вы используете tkinter, вы используете функцию

object.after(100, defineFunction)

первый родитель - это миллисекунда

это применимо к python3.x, но 2.7 я не могу быть уверен, так как я не использую этот формат

avatar
Daniel Nudelman
22 августа 2019 в 11:22
0

Я могу предложить дополнительное решение с резьбой.

У меня есть небольшой таймер в одном из моих проектов, он работает как другой поток и обновляется каждую секунду:

import threading
import tkinter as tk
import time

root = tk.Tk()
timer = tk.Text(root, width=5, height=1)
timer.insert(tk.INSERT, "00:00")
timer.pack()
def show_time():
    start = time.time()
    seconds = 0
    while True:
        if time.time() - start > 1:
            seconds += int(time.time() - start)
            start = time.time()
            cur_index = timer.index(tk.INSERT)
            cur_index = str(int(cur_index[0]) - 1) + cur_index[1:]
            timer.delete(cur_index, tk.INSERT)
            timer.insert(tk.INSERT, str(int(seconds / 60)) + ":" + str(seconds % 60))
            root.update()
thread = threading.Thread(target=show_time)
thread.start()
avatar
Mixone
5 сентября 2016 в 20:46
0

Используйте глобальную переменную, сохраняющую текущее время, когда человек нажимает start. Затем, когда пользователь нажимает svar в вашей функции svar, просто выберите текущее время, вычтите их друг из друга, и вы получите время, затем сбросьте глобальную переменную на 0 также и вуаля, у вас есть время, затраченное

avatar
Lemayzeur
24 января 2016 в 16:26
-1

Я думаю, вы можете использовать «после». Вы создаете виджет ...

time = 60 #60 seconds for example
widget = Tkinter.Label().pack()

def count():
    global time
    if time > 0:
       time -= 1
       widget.config(text="Time left: " + str(time))

       widget.after(1000, count)

Я использую python 3x Извините,