0

So I'm trying to utilize msvcrt.getch() to make an option to quit(without using KeyBoardInterrupt) anywhere in the program.

My code currently looks like this:

import msvcrt import sys

print("Press q at any time to quit")

while True:
    pressedKey = msvcrt.getch()
    if pressedKey == 'q':    
       sys.exit()
    else:
       # do some setup
       if myvar == "string":
           try:
               # do stuff
           except:
               # do stuff 
       else:
           #do stuff

How do I run the while loop to detect the keypress of q at the same time as I'm running the other (the # do stuff blocks)?

That way, if the user goes ahead with the program, they it'll only run it once. But if they hit q, then the program will quit.

evamvid
  • 831
  • 6
  • 18
  • 40
  • `msvcrt.getch()` will block if no keys have been pressed. Use `msvcrt.kbhit()` as I mention in my [answer](http://stackoverflow.com/a/22366085/355230) to another of your questions -- it doesn't block. – martineau Mar 13 '14 at 00:27

1 Answers1

1

You could read keys in a separate thread or (better) use msvcrt.kbhit() as @martineau suggested:

#!/usr/bin/env python
import msvcrt
from Queue import Empty, Queue
from threading import Thread

def read_keys(queue):
    for key in iter(msvcrt.getch, 'q'): # until `q`
        queue.put(key)
    queue.put(None) # signal the end

q = Queue()
t = Thread(target=read_keys, args=[q])
t.daemon = True # die if the program exits
t.start()

while True:
    try:
        key = q.get_nowait() # doesn't block
    except Empty:
        key = Empty
    else:
        if key is None: # end
            break
    # do stuff

If I wanted to do something in the main code when the second thread detected a certain keypress, how would I act on that?

You do not react to the key press in the main thread until code reaches q.get_nowait() again i.e., you won't notice the key press until "do stuff" finishes the current iteration of the loop. If you need to do something that may take a long time then you might need to run it in yet another thread (start new thread or use a thread pool if blocking at some point is acceptable).

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Also, how do I switch threads? i.e, If I wanted to do something in the main code when the second thread detected a certain keypress, how would I act on that? – evamvid Mar 13 '14 at 04:23