-2

I have a simple gui(tkinter) program that writes data to a file. Uses shelve. How to run shelve.close () when I want to disable the program?

Mr Korni
  • 41
  • 4
  • Hi @MrKorni, could you please add more detail to your question? Like the code you've written so far? That would be helpful for us to help you out! – toti08 Sep 18 '18 at 13:11
  • The code is long and in a different language – Mr Korni Sep 18 '18 at 13:36
  • What does it mean in a different language? Please consider that your question maybe helpful to others as well! – toti08 Sep 18 '18 at 13:42
  • Okay, I'm sorry. However, I believe that I have at least as many details as I need to answer. – Mr Korni Sep 18 '18 at 13:46

2 Answers2

3

The canonical way of closing something no-matter-what-happens is to use context managers:

with shelve.open(...) as myshelve:
    # ALL YOUR CODE HERE
    root.mainloop()

This guarantees that shelve.close() will be called, even when you get any exceptions in the code.

It is also the recommended way in the documentation:

Do not rely on the shelf being closed automatically; always call close() explicitly when you don’t need it any more, or use shelve.open() as a context manager.

Alternatively, since you're using tkinter, you can use the WM_DELETE_WINDOW event:

import tkinter as tk

root = tk.Tk()

def when_window_is_closed():
    myshelve.close()
    root.destroy()

root.protocol("WM_DELETE_WINDOW", when_window_is_closed)
root.mainloop()

This method is worse because it depends on tk firing the event. Use the context manager method instead to cover all grounds.

nosklo
  • 217,122
  • 57
  • 293
  • 297
  • Do I need to "import tkinter as tk"? Can I "from tkinter import *"? – Mr Korni Sep 18 '18 at 13:43
  • @MrKorni you can do whatever you want. I prefer to use `import tkinter as tk` to prevent **global namespace polution** - that way all names from tkinter are contained inside the `tk` module object, instead of scattered in the global namespace. – nosklo Sep 18 '18 at 14:41
0

The mainloop call stops when your GUI stops. If you want to run some code after the GUI exits just put it after mainloop().

root.mainloop() # starts the GUI and waits for the GUI to close
shelve.close() # do something after the GUI closes
Novel
  • 13,406
  • 2
  • 25
  • 41