Mhmd Admn
Mhmd Admn

Reputation: 369

How to close tkintermessagebox when it's running inside a loop?

I'm trying to make the tkinter message box appears every X seconds, and I succeeded in that but the messagebox isn't closing after pressing the cancel button, how can I fix that?

here is the code:

import Tkinter as tk
import tkMessageBox, time

root = tk.Tk()
root.withdraw()
tkMessageBox.showinfo('TITLE', 'FIRST MESSAGE')

def f():
    tkMessageBox.showinfo('TITLE', 'SECOND MESSAGE')
    tkMessageBox.showinfo('TITLE', 'THIRD MESSAGE')
    time.sleep(15)
while True:
    f()

Upvotes: 0

Views: 347

Answers (2)

martineau
martineau

Reputation: 123541

Genrally speaking you shouldn't call time.sleep() in tkinter applications because doing so interfers with the module's own event-processing loop. Instead you should use the universal widget after() method without a callback function argument.

In addition, you can make your code more "data-driven" to make changing it require less code modifications.

Below is an example which implements both of the above suggestions
(and will work in both Python 2 and 3):

try:
    import Tkinter as tk
    import tkMessageBox
except ModuleNotFoundError:  # Python 3
    import tkinter as tk
    import tkinter.messagebox as tkMessageBox


DELAY = 3000  # Milliseconds - change as desired.
MESSAGE_BOXES = [
    ('Title1', 'First Message'),
    ('Title2', 'Second Message'),
    ('Title3', 'Third Message'),
]

root = tk.Tk()
root.withdraw()

def f():
    for msg_info in MESSAGE_BOXES:
        tkMessageBox.showinfo(*msg_info)
        root.after(DELAY)
    tkMessageBox.showinfo('Note', "That's all folks!")

f()

Upvotes: 0

Mike67
Mike67

Reputation: 11342

The sleep call freezes the application. You can use the after method to repeat a function call.

import Tkinter as tk
import tkMessageBox, time

root = tk.Tk()
root.withdraw()
tkMessageBox.showinfo('TITLE', 'FIRST MESSAGE')

def f():
    tkMessageBox.showinfo('TITLE', 'SECOND MESSAGE')
    tkMessageBox.showinfo('TITLE', 'THIRD MESSAGE')
    root.after(15000, f) # call f() after 15 seconds
    
f()

input('Press Enter to exit')   # or root.mainloop()

Upvotes: 2

Related Questions