Zagorax
Zagorax

Reputation: 11890

How to end a Tkinter application which hasn't any window shown

I've this simple script and I would love to understand why it's ignoring Ctrl-C.

from Tkinter import *

def main():
    root = Tk().withdraw()

    mainloop()

if __name__ == "__main__":
    main()

I've found this other question on SO (tkinter keyboard interrupt isn't handled until tkinter frame is raised) which is basically the same. Unfortunately, the answer is not clear to me. How should I use the after() function in order to catch the signal?

Moreover, I need Tkinter only to use tkSnack and I don't want any windows to appear. So, adding a button to call root.quit() it's not a possibility.

Upvotes: 2

Views: 804

Answers (2)

patthoyts
patthoyts

Reputation: 33223

You can drive this as a Tk application with a hidden window. Following up on your previous question as well where this is all part of an mp3 player here is a sample.

from Tkinter import *
import sys,tkSnack

def terminate(root):
    root.quit()

def main(args = None):
    if args is None:
        args = sys.argv
    root = Tk()
    root.withdraw()
    tkSnack.initializeSnack(root)
    root.after(5000, terminate, root)
    track = tkSnack.Sound(file=args[1])
    track.play()
    root.mainloop()
    root.destroy()
    return 0

if __name__=='__main__':
    sys.exit(main())

In this case we hold onto the root Tk window but withdraw it before it gets a chance to be mapped on screen. We then schedule an event for 5 seconds time to terminate the application which will exit the Tk event loop and we can destroy everything and exit cleanly. This works because the play() command causes the sound track to begin playing and returns immediately. The sound data is handled with the event loop - so not running the event loop will halt its playing.

Without the after event causing early termination the application would eventually use up all the sound data from the file and then hang. The play() method takes a command to be run when it finishes playing so we can have the mainloop exit properly at the right time rather than guess the time and use after events.

Upvotes: 0

martineau
martineau

Reputation: 123541

This seems to work for me if I shift focus back to the command window before typing ctrl-C.

from Tkinter import *

def dummy(root):
    root.after(1000, dummy, root)
    print '',

def main():
    root = Tk()
    root.withdraw()
    dummy(root)
    mainloop()

if __name__ == "__main__":
    main()

Upvotes: 1

Related Questions