Mantis
Mantis

Reputation: 1387

tkinker py2app application won't close

My Tkinter application will not shutdown properly when the X in the corner is clicked. The window closes but is still visible in the dock. A force quit is required.

My Application compares two excel sheets and outputs a filtered excel sheet.

I have used py2app to make it executable.

Here is my app:

import Tkinter as tk
import pandas as pd


class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.short_path = ""
        self.long_path = ""
        self.output = ""

        self.short_path_label = tk.Label(self, text="Path to short file: ")
        self.short_path_btn = tk.Button(self, text="Browse", command=self.browse_short_path)

        self.long_path_label = tk.Label(self, text="Path to long file: ")
        self.long_path_btn = tk.Button(self, text="Browse", command=self.browse_long_path)

        self.column_label = tk.Label(self, text="Column to filter: ")
        self.column = tk.Entry(self)

        self.outpath_label = tk.Label(self, text="Output directory: ")
        self.out_path_btn = tk.Button(self, text="Browse", command=self.browse_out_path)

        self.file_name_label = tk.Label(self, text="Filename: ")
        self.file_name = tk.Entry(self)

        self.button = tk.Button(self, text="Run", command=self.on_button)

        self.short_path_label.pack()
        self.short_path_btn.pack()
        self.long_path_label.pack()
        self.long_path_btn.pack()
        self.column_label.pack()
        self.column.pack()
        self.outpath_label.pack()
        self.out_path_btn.pack()
        self.file_name_label.pack()
        self.file_name.pack()
        self.button.pack()

    def browse_short_path(self):
        from tkFileDialog import askopenfilename

        tk.Tk().withdraw()
        self.short_path = askopenfilename()

    def browse_long_path(self):
        from tkFileDialog import askopenfilename

        tk.Tk().withdraw()
        self.long_path = askopenfilename()

    def browse_out_path(self):
        from tkFileDialog import askdirectory

        tk.Tk().withdraw()
        self.output = askdirectory()

    def on_button(self):
        short_df = pd.io.excel.read_excel(self.short_path)
        long_df = pd.io.excel.read_excel(self.long_path)

        short_df = short_df[~short_df[str(self.column.get())].isin(long_df[str(self.column.get())].unique())]

        short_df.to_excel(self.output + "/" + self.file_name.get())

app = SampleApp()
app.mainloop()

Upvotes: 1

Views: 339

Answers (1)

mshildt
mshildt

Reputation: 9342

You may need to add a handler for the WM_DELETE_WINDOW protocol:

app = SampleApp()
app.protocol("WM_DELETE_WINDOW", app.destroy)
app.mainloop()

Protocols are how the Tk system interacts with the window manager. So the above connects the window manager's close button to the root window's destory() method, which will end the Tk mainloop and should exit the application.

Although, this should have been the default behavior all along. Perhaps something with py2app has caused a problem here. Or something else in your application (pandas maybe) requires some sort of shutdown. In this case you could define a shutdown function for your app and do:

app.protocol("WM_DELETE_WINDOW", app.shutdown)

To call it when the window manager's close button is pressed.

Upvotes: 1

Related Questions