This question already has answers here:
Measuring elapsed time with the Time module
(10 answers)
Closed 6 years ago.
I'm currently working on a Python 3.x project and I'm supposed to make a simple crossroad simulation with traffic lights etc. My only problem right now is that I am not aware of any way to measure time so as to use it to change the traffic lights accordingly. Is there any way to create a virtual timer which will begin as soon as the simulation starts and goes on infinitely until the window is closed? I'm considering using the time or timeit modules, but I'm a bit lost here.
Thanks in advance.
Since you included the tag tkinter, there is a tkinter-specific solution that works quite well. You can use the after method available on every widget to schedule an event to happen in the future.
In the simplest case, you can have a function that will run some other function on a given interval. For example:
import tkinter as tk
def run_periodically(func, ms):
func()
root.after(ms, run_periodically, func, ms)
def tick():
global count
count += 1
tick_label.configure(text="count: %d" % count)
count = 0
root = tk.Tk()
tick_label = tk.Label(root, text="")
tick_label.pack(padx=20, pady=20)
run_periodically(tick, 1000)
root.mainloop()
Of course, instead of having something called on a schedule, you can also just schedule the jobs as needed. For example, when the light turns red you can use after to both turn it off and turn the green on. You can then use after to turn the green off and the yellow on, and so on. Since this sounds like a homework assignment I won't provide an example.
Related
This question already has answers here:
How can I schedule updates (f/e, to update a clock) in tkinter?
(8 answers)
Closed 2 years ago.
I want to make a timer that starts when i create an instance of a class, and stop the timer when a method is called. Does anyone know how to make one? I've searched up many tutorials but got no idea what they're doing or it just doesn't fit my code. When i use self.frame.destroy() it needs to ignore the timer code so it doesn't get destroyed. The timer should include second and minutes (and milliseconds if possible). Any help will be greatly appreciated, thanks.
from tkinter import *
root = Tk()
class Start:
def __init__ (self, master):
self.master = master
#code
def timer(self):
#start timer
def end(self):
#end timer
root.mainloop()
Edit: The timer should start from 00:00:00 and not an updating clock.
Hope this helps, https://www.geeksforgeeks.org/create-stopwatch-using-python/
It is actually a stopwatch program which includes hour, minute and second, it has three buttons start, stop and reset with their respective functions.
I would like to understand why this code:
import time
for i in range(1,11):
print(i)
time.sleep(1)
shows (as it should!) numbers from 1 to 10, each every 1 second, while this code:
from tkinter import *
import time
root = Tk()
for i in range(1,11):
Label(root, text = i).grid(row=0, column=i-1, padx=5, pady =5)
time.sleep(1)
root.mainloop()
waits for 10 seconds, and then displays a window with the 10 numbers (instead of adding them one by one).
I am aware this is a silly question, but I really can't understand! Many Thanks! Alessandro
Most GUI's work differently to what you expect.
They work in an asynchronous way, which means, that you setup your windows and start an event loop.
This event loop will display all widgets, labels, etc, that you set up before calling the event loop and wait for any events (GUI events like mouse or keyboard events, timer events and perhaps network events).
When any event is encountered code associated to that event will be called and this code can request to change the GUI (show or hide elements, change labels or attributes of graphical widgets) However the change to the GUI will only be performed when you give control back to the event loop (when the code handling an event finished)
In your given code you change a label in a for loop with sleep statements, but only after the for loop is finished your main loop is being called and this is the moment, where the final state of your GUI will be displayed.
So what you encounter is a know issue for almost all GUI / asynhronous kind of applications.
You have to rewrite your code such, that you start a timer event, and when the timer event fires a function will set a label and increase the counter by 1. And if the counter is not 11 it will restart another timer
This is because the time.sleep function is before the root.mainloop function.
root.mainloop is what causes the window to appear on-screen and start doing things. Instead, I'd recommend using window.after, as that tells the window to run a function after some time when it's on-screen.
Here's an example of a modification you could make (it's not that good but it works):
from tkinter import *
import time
root = Tk()
progress = 0
end = 10
def update_progress():
global progress
progress += 1
Label(root, text = progress).grid(row=0, column=progress-1, padx=5, pady =5)
if progress < end: root.after(1000,update_progress) # Tell the window to call this function in 1000ms (1 second)
root.after(0,update_progress) # Tell the window to run the update_progress function 0ms after now.
root.mainloop()
I'd recommend looking at gelonida's answer for an explanation of why your original code didn't work, and what you need to keep in mind when programming with GUIs in the future.
Apologies if the question is a little vague, I'll edit it if necessary.
I'm creating a chess game in Python with Tkinter and want to add a chess timer.
When a player moves a piece the move() function is called, causing the piece to be moved to the correct square and the turn switches (from black to white and vice-versa) - turn is a list ["W", "B"] that keeps track of whose turn it is.
Called when a player selects a square to move to:
def move():
#code here
turn.reverse()
To time each move, I want to measure the time between consecutive execution of the move() function (i.e. time between turn switches).
To summarise:
How can I measure the time between consecutive executions of the same function?
Edit
From the answers I can see that my question was misunderstood, I'm sorry for not clarifying:
I'm not looking to measure the time it takes to execute a function (the move() function).
I am looking to measure the time between consecutive executions of a function. The answers given here assume I only want to measure the execution time of the function from start to end. You cannot assume that the move() function executes again immediately after it has finished; it is called by clicking a button so there may be a delay (thinking about the move) before the move() function is called again.
Any help would be greatly appreciated.
You can use time module of python. If i understood your question properly, Something like this can be done:
import time
initial_time = time.monotonic()
def move():
#code here
time_gap = time.monotonic() - initial_time
print(time_gap)
initial_time = time.monotonic()
turn.reverse()
This question already has an answer here:
Making a countdown timer with Python and Tkinter?
(1 answer)
Closed 6 years ago.
I'm having problems with a countdown clock that I was making in Python for a Raspberry Pi. I need to have a countdown clock that counts down from 60 minutes. When time runs out it should display a red text "GAME OVER".
I've already made one using TKinter and a for loop for the actual timer but I couldn't find any way to stop the for loop. I gave up on it.
Is there anyone nice enough to maybe write the actual timer and timer stopping part? I'm good enough at python and TKinter to do everything else that I need.
I'd recommend using generators to handle your for loop and will provide a minimal example but on StackOverflow no one is going to "write the actual timer and timer stopping part" (see What topics can I ask here)
Note this is an example I had before this question was posted and thought it would be helpful to you.
import tkinter as tk
def run_timer():
for time in range(60):
label["text"] = time #update GUI here
yield #wait until next() is called on generator
root = tk.Tk()
label = tk.Label()
label.grid()
gen = run_timer() #start generator
def update_timer():
try:
next(gen)
except StopIteration:
pass #don't call root.after since the generator is finished
else:
root.after(1000,update_timer) #1000 ms, 1 second so it actually does a minute instead of an hour
update_timer() #update first time
root.mainloop()
you will still need to figure out for yourself how to implement after_cancel() to stop it and the red "GAME OVER" text.
I need to figure out the delay between sending a command to change the background color or playing a sound and these events actually occurring using timeit.(I'm on windows, Python 2.73)
I'm doing a reaction time test where I'll record the time(using time.clock()) before either changing the background color or playing a sound. Then, when the subject presses a key I record the time again and take difference to find the reaction time.
For the sound playing, here's what I did:
import timeit
t = timeit.Timer(stmt = "winsound.PlaySound('C:\WINDOWS\media\Windows XP Error.wav', winsound.SND_FILENAME)",setup = "import winsound")
n = t.timeit(number = 100)
print n/100 -0.999
The 0.999 is the duration of the Windows XP Error.wav in seconds.
This gave me something like 56ms. I'm not sure if its reasonable and if its the right way to do it as well as should I be enabling the garbage collection or not?
For the background changing I'm having more problems. Since I'm doing the test in fullscreen mode I tried to put all of these into the setup parameter:
from Tkinter import Tk
root=Tk()
root.overrideredirect(True)
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(),root.winfo_screenheight()))
root.mainloop()
Even though I separate them all with ; I still get syntax errors. When I try it not in full screen
setup = 'from Tkinter import Tk; root=Tk(); root.mainloop()' the window actually opens, yet nothing happens and if I close it I see other errors.Invalid command name "."
The statement that I'm actually measuring is root.configure(background='red').
Here's an example of a way to create a multi-line setup string for use with timeit:
setup = """
import random
l1 = [random.randrange(100) for _ in xrange(100)]
l2 = [random.randrange(100) for _ in xrange(10)]
"""
Here's another tip. To get an accurate measurement, it's important to time things following this basic pattern:
time = min(timeit.repeat(statements, setup=setup, repeat=R, number=N))
With an R of at least 3 (R = 3). This takes the fastest value obtained by doing everything 3 times, which will eliminate differences due to the many other things running on your system in the background.
This doesn't answer your whole question, but may be helpful in your quest.