Reputation: 301
After digging around in SO for a while, I still haven't found a good answer to what I would hope is a fairly common need. Basically I need a main thread to do "stuff" until it receives input and then act on that input, then return to the original "stuff". My problem every time seems to be that my program execution seems to halt completely at the raw input, whether I call it in a thread or anywhere else. Forwarning I'm pretty novice to python, but I'd hope this shouldn't be too nasty to implement. Here is what I'm playing with (pulled from my other question where my threading question was answered handily)
So I'm trying to write a program that looks for keyboard presses and then does something in the main program based upon what the user inputs. I'm trying to run the keyboard listening in a thread and then compare whats in the variable in my main loop, but I don't ever seem to be getting the threaded keyboard input. In the below code, the print maybe updating line never happens, just the else block from the main while loop. What do i need to do so that my main loop is aware of the keys pressed by the user?
import threading
import time
kbdInput = ''
playingID = ''
def kbdListener():
global kbdInput
kbdInput = rawInput()
print "maybe updating...the kbdInput variable is: ",kbdInput
listener = threading.Thread(target=kbdListener)
while True:
print "kbdInput: ",kbdInput
print "playingID: ",playingID
if playingID != kbdInput:
print "Recieved new keyboard Input. Setting playing ID to keyboard input value"
playingID = kbdInput
else:
print "No input from keyboard detected. Sleeping 2 seconds"
time.sleep(2)
Upvotes: 8
Views: 8780
Reputation: 143
I found the accepted answer didn't work for me - it would still block at raw_input even in a separate thread. However, when I switched the threads around it worked right away.
import threading
def mainWork():
while 1:
#whatever you wanted to do until an input is received
myThread = threading.Thread(target=mainWork)
myThread.start()
while 1:
input = raw_input()
#do stuff with input when it is received
Upvotes: 1
Reputation: 441
If you actually want to keep the while
loop going on forever, you will need to create a new thread and start it, each time the old one has finished.
I updated the example in the question to make that work:
import threading
import time
kbdInput = ''
playingID = ''
finished = True
def kbdListener():
global kbdInput, finished
kbdInput = raw_input("> ")
print "maybe updating...the kbdInput variable is: {}".format(kbdInput)
finished = True
while True:
print "kbdInput: {}".format(kbdInput)
print "playingID: {}".format(playingID)
if playingID != kbdInput:
print "Received new keyboard Input. Setting playing ID to keyboard input value"
playingID = kbdInput
else:
print "No input from keyboard detected. Sleeping 2 seconds"
if finished:
finished = False
listener = threading.Thread(target=kbdListener)
listener.start()
time.sleep(2)
Upvotes: 2
Reputation: 8421
In addition to MydKnight's answer (starting the thread), you need to change rawInput
to raw_input
, and it needs to be in some sort of while
loop otherwise you'll only get one raw_input()
logged.
Upvotes: 1
Reputation: 1995
You created a thread but forget to start it:
listener = threading.Thread(target=kbdListener)
listener.start()
Upvotes: 2