Reputation: 176
I wrote a small routine in python 2.7, which waits for some time (say, 10 minutes) but immediately exits if a key is pressed by the the user.
I'm on Windows (7, 64-bit), so I tried using the msvcrt library:
import sys
import msvcrt
from time import sleep
def sleep_sec(secstosleep, allowskip = True):
waitinterval_ms = 0.050
nwaits = int(secstosleep * 1000 / waitinterval)
sys.stdout.write("\n Sleeping for %s seconds. You can press CTRL-F12 to skip.\n\n" % secstosleep)
for sl in range(0, nwaits + 1):
sleep(waitinterval_ms)
if allowskip:
# Check if User has pressed CTRL-F12 to stop waiting
if = msvcrt.kbhit():
kp = msvcrt.getch()
if kp == '\xe0':
print "\a" # Beep once
sys.stdout.write("\nSleep interrupted by User\n")
break
In effect it works quite well, except for the fact that it will break if the user hits either F12, F11 or Cursor Up key: I found out that if I press F12, getch() will return the '\xe0', but it seems the same code is also returned by the other mentioned keys; no way to trap CTRL, SHIFT, ALT, etc.
I would like to force the user pressing CTRL-F12, instead, to avoid quitting the wait by inadvertently hitting one of those keys.
Am I doing something wrong? Is there a way to intercept CTRL, ALT or SHIFT being pressed along with another key?
Thanks in advance, Max - Italy
Upvotes: 2
Views: 13454
Reputation: 7303
I will suggest you to use keyboard
module. It has a lot of features and is pretty simple to use. You can also use it to detect keypresses. Examples:
If you want to detect key a
:
import keyboard as kb
while True:
if kb.is_pressed("a"):break
You can also use it to detect combinations. For example , if you want to check if a
and b
are pressed at the same time:
import keyboard as kb
while True:
if kb.is_pressed("a+b"):break
So , you can use to to detect if ctrl
and f12
are pressed:
import keyboard as kb
while True:
if kb.is_pressed("ctrl+f12"):break
A sample according to your posted code:
import sys
import keyboard as kb
import time
def sleep_sec(secstosleep,allowskip=True):
t = time.time() #getting time in sec
sys.stdout.write("\n Sleeping for %s seconds. You can press CTRL-F12 to skip.\n\n"% secstosleep)
if allowskip:
while time.time() - t <= secstosleep: #while current time(in sec) - t is less than secstosleep
if kb.is_pressed("ctrl+f11"): #if ctrl and f12 are pressed
print "\a"
sys.stdout.write("\nSleep interrupted by User\n")
quit(0)
sleep_sec(10*60) # 10*60 == 10 min
Upvotes: 7
Reputation: 176
As suggested by Daniel, I've modified my code like this:
import sys
import msvcrt
from time import sleep
def sleep_sec(secstosleep, allowskip = True):
waitinterval_ms = 0.050
nwaits = int(secstosleep * 1000 / waitinterval)
sys.stdout.write("\n Sleeping for %s seconds. You can press CTRL-F12 to skip.\n\n" % secstosleep)
for sl in range(0, nwaits + 1):
sleep(waitinterval_ms)
if allowskip:
# Check if User has pressed CTRL-F12 to stop waiting
if = msvcrt.kbhit():
kp = msvcrt.getch()
if kp == '\xe0':
kp += msvcrt.getch()
if kp == '\xe0\x8a': # \x8a is the keycode for CTRL-F12
print "\a" # Beep once
sys.stdout.write("\nSleep interrupted by User\n")
break
I've also noticed that different keycodes are returned for F12, CTRL-F12 and SHIFT-F12, so keystrokes can be easily recognized.
Thanks again, Daniel!
Max.
Upvotes: 0
Reputation: 8491
From the msvcrt
manual for msvcrt.getch()
:
[..] If the pressed key was a special function key, this will return '\000' or '\xe0'; the next call will return the keycode.
Just call getch()
again to get the actual keycode
Upvotes: 2