Non-blocking raw_input () in python

After a lot of work at SO, I still have not found a good answer to what I hope is a fairly common need. Basically, I need the main thread to make the “material” until it receives an input, and then acts on this input, and then returns to the original “material”. My problem every time it seems that my program execution seems to stop completely at the original input, I call it in a thread or elsewhere. Warning I am new to python, but I hope this should not be too nasty to implement. Here is what I'm playing with (pulled from my other question where my threaded question was satisfied)

So, I'm trying to write a program that searches for keystrokes, and then does something in the main program, based on what the user enters. I am trying to start listening to the keyboard in a stream, and then compare something in a variable in my main loop, but I'm never going to enter keyboard input. In the code below, the print line can never be updated, but only the else block from the main while loop. What do I need to do so that my main loop knows about the keystrokes 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)
+4
source share
4 answers

If you really want the loop whileto last forever, you will need to create a new thread and start it every time the old one is completed.

I updated the example in the question to make this 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)
+1

, :

listener = threading.Thread(target=kbdListener)
listener.start()
+2

In addition to MydKnight's answer (start of stream) you need to change rawInputto raw_input, and it should be in the form of a loop while, otherwise you will only get one raw_input()registered.

+1
source

I found that the accepted answer did not work for me - it will still be blocked in raw_input even in a separate thread. However, when I switched flows 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
0
source

All Articles