Search code examples
pythonraw-input

Terminating raw_input() if other text displays


I have a simple server application I made in Python using SocketServer, it has a very primitive command line type input system. My main problem here is that when the server receives a message, it prints it to the screen. This is all fine and good except that the raw_input function is still waiting for text to entered and checked. Is there a way to, in the server handle() function, stop the raw_input or raise some exception that would end the input and display the information that the server is receiving?

Thanks,
Zack.


Solution

  • As far as I know, this isn't possible because raw_input accepts input from the python command console. There are, however, some ways to get around it that may not be expected:

    1 - Instead of using the console, create a simple Tkinter window with the output and an input line. Create a custom print function that appends the message to the end of the window text, (Which could be in a scroll bar using a fixed-width font) and then create a command prompt box that responds to enter. The code for that would look something like this:

    from Tkinter import *
    root = Tk()
    topframe=Frame(root)
    bottomframe=Frame(root)
    bottomframe.pack(side=BOTTOM,fill=X)
    topframe.pack(side=TOP,fill=BOTH)
    scrollbar = Scrollbar(topframe)
    scrollbar.pack(side=RIGHT,fill=Y)
    text = Text(topframe,yscrollcommand=scrollbar.set)
    text.pack(side=LEFT,fill=BOTH)
    scrollbar.config(command=text.yview)
    text.config(state=DISABLED)
    v = StringVar()
    e = Entry(bottomframe,textvariable=v)
    def submit():
        command = v.get()
        v.set('')
        #your input handling code goes here.
        wprint(command)
        #end your input handling
    e.bind('<Return>',submit)
    button=Button(bottomframe,text='RUN',command=submit)
    button.pack(side=RIGHT)
    e.pack(expand=True,side=LEFT,fill=X)
    def wprint(obj):
        text.config(state=NORMAL)
        text.insert(END,str(obj)+'\n')
        text.config(state=DISABLED)
    root.mainloop()
    

    Another option would be to create your own print and raw_input methods to look something like this:

    import threading
    wlock=threading.Lock()
    printqueue=[]
    rinput=False
    def winput(text):
        with wlock:
            global printqueue,rinput
            rinput=True
            text = raw_input(text)
            rinput=False
            for text in printqueue:
                print(text)
            printqueue=[]
            return text
    def wprint(obj):
        global printqueue
        if not(rinput):
            print(str(obj))
        else:
            printqueue.append(str(obj))