How to use timer in pywin32
Question:
I want the logging function to run every 1 second using Python and pywin32 timer module. Here is my code
import timer
i = 0
def logging():
global i
print(str(i))
i += 1
timer.set_timer(1000, logging)
However I don’t see any output on screen. I’m not sure what I’m doing wrong here.
Answers:
See timer_demo.py (reproduced below). The pywin32
timer is based on Windows messages so a message loop needs to be implemented.
# -*- Mode: Python; tab-width: 4 -*-
#
# This module, and the timer.pyd core timer support, were written by
# Sam Rushing ([email protected])
import timer
import time
# Timers are based on Windows messages. So we need
# to do the event-loop thing!
import win32event, win32gui
# glork holds a simple counter for us.
class glork:
def __init__ (self, delay=1000, max=10):
self.x = 0
self.max = max
self.id = timer.set_timer (delay, self.increment)
# Could use the threading module, but this is
# a win32 extension test after all! :-)
self.event = win32event.CreateEvent(None, 0, 0, None)
def increment (self, id, time):
print('x = %d' % self.x)
self.x = self.x + 1
# if we've reached the max count,
# kill off the timer.
if self.x > self.max:
# we could have used 'self.id' here, too
timer.kill_timer (id)
win32event.SetEvent(self.event)
# create a counter that will count from '1' thru '10', incrementing
# once a second, and then stop.
def demo (delay=1000, stop=10):
g = glork(delay, stop)
# Timers are message based - so we need
# To run a message loop while waiting for our timers
# to expire.
start_time = time.time()
while 1:
# We can't simply give a timeout of 30 seconds, as
# we may continouusly be recieving other input messages,
# and therefore never expire.
rc = win32event.MsgWaitForMultipleObjects(
(g.event,), # list of objects
0, # wait all
500, # timeout
win32event.QS_ALLEVENTS, # type of input
)
if rc == win32event.WAIT_OBJECT_0:
# Event signalled.
break
elif rc == win32event.WAIT_OBJECT_0+1:
# Message waiting.
if win32gui.PumpWaitingMessages():
raise RuntimeError("We got an unexpected WM_QUIT message!")
else:
# This wait timed-out.
if time.time()-start_time > 30:
raise RuntimeError("We timed out waiting for the timers to expire!")
if __name__=='__main__':
demo()
Output (with 1-second delay between lines):
x = 0
x = 1
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
x = 10
Minimal example that will count forever:
import timer
import win32gui
import win32event
i = 0
def logging(timer_id, current_time):
global i
print(i)
i += 1
timer.set_timer(1000, logging)
# The message loop waits for a windows message,
# then dispatches it. The callback won't run
# without this processing.
while True:
rc = win32event.MsgWaitForMultipleObjects((), False, win32event.INFINITE, win32event.QS_ALLEVENTS)
if rc == win32event.WAIT_OBJECT_0:
win32gui.PumpWaitingMessages()
If you just want a background counter, you could just use a thread:
import threading
import time
def logging():
i = 0
while True:
time.sleep(1)
print(i)
i += 1
threading.Thread(target=logging).start()
# For some foreground activity:
while True:
print('.', end='', flush=True)
time.sleep(.2)
Output:
.....0
.....1
.....2 # etc...
I want the logging function to run every 1 second using Python and pywin32 timer module. Here is my code
import timer
i = 0
def logging():
global i
print(str(i))
i += 1
timer.set_timer(1000, logging)
However I don’t see any output on screen. I’m not sure what I’m doing wrong here.
See timer_demo.py (reproduced below). The pywin32
timer is based on Windows messages so a message loop needs to be implemented.
# -*- Mode: Python; tab-width: 4 -*-
#
# This module, and the timer.pyd core timer support, were written by
# Sam Rushing ([email protected])
import timer
import time
# Timers are based on Windows messages. So we need
# to do the event-loop thing!
import win32event, win32gui
# glork holds a simple counter for us.
class glork:
def __init__ (self, delay=1000, max=10):
self.x = 0
self.max = max
self.id = timer.set_timer (delay, self.increment)
# Could use the threading module, but this is
# a win32 extension test after all! :-)
self.event = win32event.CreateEvent(None, 0, 0, None)
def increment (self, id, time):
print('x = %d' % self.x)
self.x = self.x + 1
# if we've reached the max count,
# kill off the timer.
if self.x > self.max:
# we could have used 'self.id' here, too
timer.kill_timer (id)
win32event.SetEvent(self.event)
# create a counter that will count from '1' thru '10', incrementing
# once a second, and then stop.
def demo (delay=1000, stop=10):
g = glork(delay, stop)
# Timers are message based - so we need
# To run a message loop while waiting for our timers
# to expire.
start_time = time.time()
while 1:
# We can't simply give a timeout of 30 seconds, as
# we may continouusly be recieving other input messages,
# and therefore never expire.
rc = win32event.MsgWaitForMultipleObjects(
(g.event,), # list of objects
0, # wait all
500, # timeout
win32event.QS_ALLEVENTS, # type of input
)
if rc == win32event.WAIT_OBJECT_0:
# Event signalled.
break
elif rc == win32event.WAIT_OBJECT_0+1:
# Message waiting.
if win32gui.PumpWaitingMessages():
raise RuntimeError("We got an unexpected WM_QUIT message!")
else:
# This wait timed-out.
if time.time()-start_time > 30:
raise RuntimeError("We timed out waiting for the timers to expire!")
if __name__=='__main__':
demo()
Output (with 1-second delay between lines):
x = 0
x = 1
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
x = 10
Minimal example that will count forever:
import timer
import win32gui
import win32event
i = 0
def logging(timer_id, current_time):
global i
print(i)
i += 1
timer.set_timer(1000, logging)
# The message loop waits for a windows message,
# then dispatches it. The callback won't run
# without this processing.
while True:
rc = win32event.MsgWaitForMultipleObjects((), False, win32event.INFINITE, win32event.QS_ALLEVENTS)
if rc == win32event.WAIT_OBJECT_0:
win32gui.PumpWaitingMessages()
If you just want a background counter, you could just use a thread:
import threading
import time
def logging():
i = 0
while True:
time.sleep(1)
print(i)
i += 1
threading.Thread(target=logging).start()
# For some foreground activity:
while True:
print('.', end='', flush=True)
time.sleep(.2)
Output:
.....0
.....1
.....2 # etc...