RnRoger
RnRoger

Reputation: 690

closing tkinter window together with messagebox error window

In my script I sometimes call my ErrorWindow class to show an error message. This creates an empty tkinter window and a messagebox error window. I either only want the messagebox window, or I want the tkinter window to close automatically when I close the error window. I've tried two pieces of code:

class ErrorWindow:
    def __init__(self,error_message):
        self.error_window = tk.Tk()
        messagebox.showerror("ERROR",error_message,command=self.close)
        self.error_window.protocol("WM_DELETE_WINDOW", self.close)
        self.error_window.mainloop()

    def close(self):
        self.error_window.destroy()

.

class ErrorWindow:
    def __init__(self,error_message):

        messagebox.showerror("ERROR",error_message) #automatically creates a tk window too

But even with the second one, the tkinter window remains after I close the messagebox.

How can I program the class so that I only have to press a button (either Ok or the X in the top right of a window) once to close all windows (whether that is one or two)?

Upvotes: 1

Views: 5232

Answers (3)

MarcusAurelius
MarcusAurelius

Reputation: 73

The small function below will do the job. By setting the type you can choose for: info, warning or error message box, the default is 'Info'. You can set also the timeout, the default is 2.5 seconds.

def showMessage(message, type='info', timeout=2500):
    import tkinter as tk
    from tkinter import messagebox as msgb

    root = tk.Tk()
    root.withdraw()
    try:
        root.after(timeout, root.destroy)
        if type == 'info':
            msgb.showinfo('Info', message, master=root)
        elif type == 'warning':
            msgb.showwarning('Warning', message, master=root)
        elif type == 'error':
            msgb.showerror('Error', message, master=root)
    except:
        pass

Call the function as follow: For message type 'Info' and timeout of 2.5 seconds:

showMessage('Your message')

Or by your own settings for type message 'Error' and timeout 4 seconds:

showMessage('Your message', type='error', timeout=4000)

Upvotes: 1

Terry Jan Reedy
Terry Jan Reedy

Reputation: 19209

You did not specify whether there is just one place or multiple places where you might want want an error message. If the latter, you can create and withdraw a tk window just once. I believe a wrapper function rather than class should be sufficient for your purposes.

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
# consider placing root to control where messagebox appears
root.withdraw()

def showerror(message):
    messagebox.showerror('XYZ ERROR', message, parent=root)

To avoid possible problems, I always use an explicit master or parent for everything and never depend on _default_root.

Upvotes: 1

Novel
Novel

Reputation: 13729

You need to withdraw the main window:

class ErrorWindow:
    def __init__(self,error_message):
        if not tk._default_root: # check for existing Tk instance
            error_window = tk.Tk()
            error_window.withdraw()
        messagebox.showerror("ERROR",error_message)

This has no business as a class. You should remake this a simple function.

Upvotes: 2

Related Questions