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

schluchc
  • 3,924
  • 2
  • 15
  • 13
  • "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. – S.Lott Jan 04 '11 at 11:23
  • 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? – schluchc Jan 04 '11 at 12:41
  • @ S.Lott: I edited the question, please tell me if it is clear now. – schluchc Jan 04 '11 at 12:48
  • "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? – S.Lott Jan 04 '11 at 14:40
  • 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. – schluchc Jan 04 '11 at 15:24
  • 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. – schluchc Jan 04 '11 at 16:28
  • Running into the same issue, I've posted my solution [here](http://stackoverflow.com/a/25419716/1224456) – Nagasaki45 Aug 21 '14 at 06:39

2 Answers2

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()
Martin Trigaux
  • 5,311
  • 9
  • 45
  • 58
  • 1
    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. – schluchc Jan 04 '11 at 13:11
  • Maybe it doesn't on windows because this code works on linux (if so then forget what I said). – Martin Trigaux Jan 04 '11 at 13:19
  • You are right, using 'thread.interrupt_main()' it does also work on Windows. Thanks! – schluchc Jan 04 '11 at 13:40
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.

moinudin
  • 134,091
  • 45
  • 190
  • 216
  • 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. – schluchc Jan 04 '11 at 09:17
  • @christian Ah, you're on Windows (just read the question again). Will update answer. – moinudin Jan 04 '11 at 09:19
  • Thank you very much, that will do it. But is there really no platform independent solution to have a non-blocking CLI reader? – schluchc Jan 04 '11 at 09:41
  • @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. – moinudin Jan 04 '11 at 10:05