Often, a GUI application will need to tell the user something. Using what we have learned at the moment, we could make several Label
widgets which update depending on the results of some other functions. This would get tedious and take up a lot of space within the application's window.
A much better way to achieve this is to use a pop-up window. These can be created manually, but Tkinter also comes with a few pre-built pop-ups which are already laid out and ready to display any message the programmer passes to them.
Let's adjust our Hello World
application to utilize these windows to display the chosen message to the user.
Import the messagebox
module with the following statement:
import tkinter.messagebox as msgbox
Now update the non-init methods to utilize this module:
def say_hello(self): msgbox.showinfo("Hello", "Hello World!") def say_goodbye(self): self.label_text.set("Window will close in 2 seconds") msgbox.showinfo("Goodbye!", "Goodbye, it's been fun!") self.after(2000, self.destroy)
Run this version of our application and try out both buttons.
You should be able to see what the two arguments to showinfo
do.
The first argument is the window's title bar text. If you didn't notice, click the Say Hello
button again – you should see the word Hello
inside the title bar of the pop-up window.
Clicking the Say Goodbye
button will yield a pop-up message with Goodbye!
in the title bar.
The second argument is a string containing the information which will be written inside the box.
The showinfo
box contains just one button—an OK
button. Clicking this button dismisses the window:
A showinfo box
While a messagebox
window is displayed, the main window is effectively paused. The Say Goodbye
button demonstrates this well. The line which tells the main window to close after 2 seconds does not get executed until the messagebox
is dismissed.
Try clicking the Say Goodbye
button and waiting for more than 2 seconds. You will see that the main window stays open until 2 seconds after you click OK to close the messagebox
window. This is important to remember.
If, for example, you are processing a large list of items and you wish to alert the user to their status, it's best to wait until all of the items are processed before using showinfo
. If you put a showinfo
box after each item, the user will have to continually close them in order to allow the main window to continue processing.
If the information to convey is more serious, you can let the user know with showwarning
.
If something goes wrong, tell the user with showerror
instead.
Both of these function the same as the showinfo
box that we have practiced but display a different image inside the box.
Try changing the showinfo
in say_hello
to a showwarning
and the showinfo
in say_goodbye
to a showerror
to see what these boxes will look like.
Should you require something back from the user, Tkinter has four more message boxes for you:
askquestion
askyesno
askokcancel
askretrycancel
askquestion
will allow any question to be passed in and provides Yes
and No
answers. These are returned to the program as the string literals "yes"
and "no"
.
askyesno
does the same, but will return 1 on Yes
and nothing on No
.
askokcancel
provides OK
and Cancel
buttons to the user. OK
returns 1
and Cancel
nothing.
askretrycancel
provides Retry
and Cancel
buttons. Retry
returns 1
and Cancel
nothing.
Despite the seemingly large number of choices, these all do pretty much the same thing. There doesn't seem to be much of a use case for askquestion
over askyesno
since they provide the same button choices, but askquestion
will produce cleaner code thanks to the return values.
Let's see askyesno
in action within our Hello World
application.
Change the say_goodbye
method to the following:
def say_goodbye(self): if msgbox.askyesno("Close Window?", "Would you like to close this window?"): self.label_text.set("Window will close in 2 seconds") self.after(2000, self.destroy) else: msgbox.showinfo("Not Closing", "Great! This window will stay open.")
Run this application and try clicking the Say Goodbye
button. You will now be asked whether you want to close the window. Give both No
and Yes
a try:
Our askyesno box
From the code for this function, you should see that the askyesno
method can be treated like a Boolean statement. If you don't like doing this in one go, you could always use a variable such as the following:
close = msgbox.askyesno("Close Window?", "Would you like to close this window?") if close: self.close()