Python: How to quit CLI when stuck in blocking raw_input?
Asked Answered
H

2

2

I have a GUI program which should also be controllable via CLI (for monitoring). The CLI is implemented in a while loop using raw_input. If I quit the program via a GUI close button, it hangs in raw_input and does not quit until it gets an input.

How can I immediately abort raw_input without entering an input?

I run it on WinXP but I want it to be platform independent, it should also work within Eclipse since it is a developer tool. Python version is 2.6.

I searched stackoverflow for hours and I know there are many answers to that topic, but is there really no platform independent solution to have a non-blocking CLI reader?

If not, what would be the best way to overcome this problem?

Thanks

Helvetii answered 4/1, 2011 at 8:55 Comment(7)
"without pressing an additional key to get out of the raw_input?" What does this mean? Can you explain what you mean by this? End-of-file is a key. Control-C to kill the program is a key. What is the "additional" key you're worried about? Please be specific.Meagre
To quit the program I can either enter 'quit' in the CLI or close it via GUI. If I quit the program via GUI, the CLI hangs in raw_input until I enter something in the CLI. How can I immediately abort raw_input without the need to enter an input?Helvetii
@ S.Lott: I edited the question, please tell me if it is clear now.Helvetii
"I can either enter 'quit' in the CLI or close it via GUI"? That sounds like a toweringly bad design. You should get rid of the CLI and implement whatever command-response business is going on as a proper part of the GUI. A simple editable text widget is all you need. But CLI + non-CLI user interface is a recipe for disaster. Why are you doing it this way?Meagre
It was mainly out of historical reasons, the program and the GUI was already finished then a CLI was required, so I implemented it in the console thinking that this would be the simplest way. I'll think about that.Helvetii
Another reason is that the program is only used company internal as a dev tool and it was more important to have maximum flexibility than useability.Helvetii
Running into the same issue, I've posted my solution hereWexford
B
2

That's not maybe the best solution but you could use the thread module which has a function thread.interrupt_main(). So can run two thread : one with your raw_input method and one which can give the interruption signal. The upper level thread raise a KeyboardInterrupt exception.

import thread
import time

def main():
    try:
        m = thread.start_new_thread(killable_input, tuple())
        while 1:
            time.sleep(0.1) 
    except KeyboardInterrupt:
        print "exception" 

def killable_input():
    w = thread.start_new_thread(normal_input, tuple())
    i = thread.start_new_thread(wait_sometime, tuple())


def normal_input():
    s = raw_input("input:")


def wait_sometime():
    time.sleep(4) # or any other condition to kill the thread
    print "too slow, killing imput"
    thread.interrupt_main()

if __name__ == '__main__':
    main()
Boudreau answered 4/1, 2011 at 12:52 Comment(3)
If I'm right, exceptions cannot be handled before raw_input is finished. So it is still an input needed and after that, the exception can be handled. I already tried to throw an exception from another thread.Helvetii
Maybe it doesn't on windows because this code works on linux (if so then forget what I said).Boudreau
You are right, using 'thread.interrupt_main()' it does also work on Windows. Thanks!Helvetii
O
1

Depending on what GUI toolkit you're using, find a way to hook up an event listener to the close window action and make it call win32api.TerminateProcess(-1, 0).

For reference, on Linux calling sys.exit() works.

Ot answered 4/1, 2011 at 9:0 Comment(4)
I call sys.exit() but the problem is that exit waits for raw_input to end which does not happen before I press another key.Helvetii
@christian Ah, you're on Windows (just read the question again). Will update answer.Ot
Thank you very much, that will do it. But is there really no platform independent solution to have a non-blocking CLI reader?Helvetii
@christian I'm not much of a Windows dev, so I can't say for sure. But if sys.exit() doesn't work for you, there is no other built-in Python function.Ot

© 2022 - 2024 — McMap. All rights reserved.