18. Dialogs — Python GTK+ 3 Tutorial 3.4 documentation (original) (raw)
Dialog windows are very similar to standard windows, and are used to provide or retrieve information from the user. They are often used to provide a preferences window, for example. The major difference a dialog has is some prepacked widgets which layout the dialog automatically. From there, we can simply add labels, buttons, check buttons, etc. Another big difference is the handling of responses to control how the application should behave after the dialog has been interacted with.
There are several derived Dialog classes which you might find useful.Gtk.MessageDialog is used for most simple notifications. But at other times you might need to derive your own dialog class to provide more complex functionality.
18.1. Custom Dialogs
To pack widgets into a custom dialog, you should pack them into theGtk.Box, available via Gtk.Dialog.get_content_area(). To just add a Gtk.Button to the bottom of the dialog, you could use theGtk.Dialog.add_button() method.
A ‘modal’ dialog (that is, one which freezes the rest of the application from user input), can be created by calling Gtk.Dialog.set_modal
on the dialog or set the flags
argument of the Gtk.Dialog constructor to include the Gtk.DialogFlags.MODAL flag.
Clicking a button will emit a signal called “response”. If you want to block waiting for a dialog to return before returning control flow to your code, you can call Gtk.Dialog.run(). This method returns an int which may be a value from the Gtk.ResponseType or it could be the custom response value that you specified in the Gtk.Dialog constructor or Gtk.Dialog.add_button().
Finally, there are two ways to remove a dialog. The Gtk.Widget.hide() method removes the dialog from view, however keeps it stored in memory. This is useful to prevent having to construct the dialog again if it needs to be accessed at a later time. Alternatively, theGtk.Widget.destroy() method can be used to delete the dialog from memory once it is no longer needed. It should be noted that if the dialog needs to be accessed after it has been destroyed, it will need to be constructed again otherwise the dialog window will be empty.
18.1.1. Example
1import gi 2 3gi.require_version("Gtk", "3.0") 4from gi.repository import Gtk 5 6 7class DialogExample(Gtk.Dialog): 8 def init(self, parent): 9 super().init(title="My Dialog", transient_for=parent, flags=0) 10 self.add_buttons( 11 Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK 12 ) 13 14 self.set_default_size(150, 100) 15 16 label = Gtk.Label(label="This is a dialog to display additional information") 17 18 box = self.get_content_area() 19 box.add(label) 20 self.show_all() 21 22 23class DialogWindow(Gtk.Window): 24 def init(self): 25 Gtk.Window.init(self, title="Dialog Example") 26 27 self.set_border_width(6) 28 29 button = Gtk.Button(label="Open dialog") 30 button.connect("clicked", self.on_button_clicked) 31 32 self.add(button) 33 34 def on_button_clicked(self, widget): 35 dialog = DialogExample(self) 36 response = dialog.run() 37 38 if response == Gtk.ResponseType.OK: 39 print("The OK button was clicked") 40 elif response == Gtk.ResponseType.CANCEL: 41 print("The Cancel button was clicked") 42 43 dialog.destroy() 44 45 46win = DialogWindow() 47win.connect("destroy", Gtk.main_quit) 48win.show_all() 49Gtk.main()
18.2. MessageDialog
Gtk.MessageDialog is a convenience class, used to create simple, standard message dialogs, with a message, an icon, and buttons for user response. You can specify the type of message and the text in the Gtk.MessageDialogconstructor, as well as specifying standard buttons.
In some dialogs which require some further explanation of what has happened, a secondary text can be added. In this case, the primary message entered when creating the message dialog is made bigger and set to bold text. The secondary message can be set by calling Gtk.MessageDialog.format_secondary_text().
18.2.1. Example
1import gi 2 3gi.require_version("Gtk", "3.0") 4from gi.repository import Gtk 5 6 7class MessageDialogWindow(Gtk.Window): 8 def init(self): 9 super().init(title="MessageDialog Example") 10 11 box = Gtk.Box(spacing=6) 12 self.add(box) 13 14 button1 = Gtk.Button(label="Information") 15 button1.connect("clicked", self.on_info_clicked) 16 box.add(button1) 17 18 button2 = Gtk.Button(label="Error") 19 button2.connect("clicked", self.on_error_clicked) 20 box.add(button2) 21 22 button3 = Gtk.Button(label="Warning") 23 button3.connect("clicked", self.on_warn_clicked) 24 box.add(button3) 25 26 button4 = Gtk.Button(label="Question") 27 button4.connect("clicked", self.on_question_clicked) 28 box.add(button4) 29 30 def on_info_clicked(self, widget): 31 dialog = Gtk.MessageDialog( 32 transient_for=self, 33 flags=0, 34 message_type=Gtk.MessageType.INFO, 35 buttons=Gtk.ButtonsType.OK, 36 text="This is an INFO MessageDialog", 37 ) 38 dialog.format_secondary_text( 39 "And this is the secondary text that explains things." 40 ) 41 dialog.run() 42 print("INFO dialog closed") 43 44 dialog.destroy() 45 46 def on_error_clicked(self, widget): 47 dialog = Gtk.MessageDialog( 48 transient_for=self, 49 flags=0, 50 message_type=Gtk.MessageType.ERROR, 51 buttons=Gtk.ButtonsType.CANCEL, 52 text="This is an ERROR MessageDialog", 53 ) 54 dialog.format_secondary_text( 55 "And this is the secondary text that explains things." 56 ) 57 dialog.run() 58 print("ERROR dialog closed") 59 60 dialog.destroy() 61 62 def on_warn_clicked(self, widget): 63 dialog = Gtk.MessageDialog( 64 transient_for=self, 65 flags=0, 66 message_type=Gtk.MessageType.WARNING, 67 buttons=Gtk.ButtonsType.OK_CANCEL, 68 text="This is an WARNING MessageDialog", 69 ) 70 dialog.format_secondary_text( 71 "And this is the secondary text that explains things." 72 ) 73 response = dialog.run() 74 if response == Gtk.ResponseType.OK: 75 print("WARN dialog closed by clicking OK button") 76 elif response == Gtk.ResponseType.CANCEL: 77 print("WARN dialog closed by clicking CANCEL button") 78 79 dialog.destroy() 80 81 def on_question_clicked(self, widget): 82 dialog = Gtk.MessageDialog( 83 transient_for=self, 84 flags=0, 85 message_type=Gtk.MessageType.QUESTION, 86 buttons=Gtk.ButtonsType.YES_NO, 87 text="This is an QUESTION MessageDialog", 88 ) 89 dialog.format_secondary_text( 90 "And this is the secondary text that explains things." 91 ) 92 response = dialog.run() 93 if response == Gtk.ResponseType.YES: 94 print("QUESTION dialog closed by clicking YES button") 95 elif response == Gtk.ResponseType.NO: 96 print("QUESTION dialog closed by clicking NO button") 97 98 dialog.destroy() 99 100 101win = MessageDialogWindow() 102win.connect("destroy", Gtk.main_quit) 103win.show_all() 104Gtk.main()
18.3. FileChooserDialog
The Gtk.FileChooserDialog is suitable for use with “File/Open” or “File/Save” menu items. You can use all of the Gtk.FileChooser methods on the file chooser dialog as well as those for Gtk.Dialog.
When creating a Gtk.FileChooserDialog you have to define the dialog’s purpose:
- To select a file for opening, as for a File/Open command, useGtk.FileChooserAction.OPEN
- To save a file for the first time, as for a File/Save command, useGtk.FileChooserAction.SAVE, and suggest a name such as “Untitled” with Gtk.FileChooser.set_current_name().
- To save a file under a different name, as for a File/Save As command, useGtk.FileChooserAction.SAVE, and set the existing filename withGtk.FileChooser.set_filename().
- To choose a folder instead of a file, use Gtk.FileChooserAction.SELECT_FOLDER.
Gtk.FileChooserDialog inherits from Gtk.Dialog, so buttons have response IDs such as Gtk.ResponseType.ACCEPT and Gtk.ResponseType.CANCELwhich can be specified in the Gtk.FileChooserDialog constructor. In contrast to Gtk.Dialog, you can not use custom response codes withGtk.FileChooserDialog. It expects that at least one button will have of the following response IDs:
When the user is finished selecting files, your program can get the selected names either as filenames (Gtk.FileChooser.get_filename()) or as URIs (Gtk.FileChooser.get_uri()).
By default, Gtk.FileChooser only allows a single file to be selected at a time. To enable multiple files to be selected, useGtk.FileChooser.set_select_multiple(). Retrieving a list of selected files is possible with either Gtk.FileChooser.get_filenames() orGtk.FileChooser.get_uris().
Gtk.FileChooser also supports a variety of options which make the files and folders more configurable and accessible.
- Gtk.FileChooser.set_local_only(): Only local files can be selected.
Gtk.FileChooser.show_hidden()
: Hidden files and folders are displayed.- Gtk.FileChooser.set_do_overwrite_confirmation(): If the file chooser was configured in Gtk.FileChooserAction.SAVE mode, it will present a confirmation dialog if the user types a file name that already exists.
Furthermore, you can specify which kind of files are displayed by creatingGtk.FileFilter objects and calling Gtk.FileChooser.add_filter(). The user can then select one of the added filters from a combo box at the bottom of the file chooser.
18.3.1. Example
1import gi 2 3gi.require_version("Gtk", "3.0") 4from gi.repository import Gtk 5 6 7class FileChooserWindow(Gtk.Window): 8 def init(self): 9 super().init(title="FileChooser Example") 10 11 box = Gtk.Box(spacing=6) 12 self.add(box) 13 14 button1 = Gtk.Button(label="Choose File") 15 button1.connect("clicked", self.on_file_clicked) 16 box.add(button1) 17 18 button2 = Gtk.Button(label="Choose Folder") 19 button2.connect("clicked", self.on_folder_clicked) 20 box.add(button2) 21 22 def on_file_clicked(self, widget): 23 dialog = Gtk.FileChooserDialog( 24 title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN 25 ) 26 dialog.add_buttons( 27 Gtk.STOCK_CANCEL, 28 Gtk.ResponseType.CANCEL, 29 Gtk.STOCK_OPEN, 30 Gtk.ResponseType.OK, 31 ) 32 33 self.add_filters(dialog) 34 35 response = dialog.run() 36 if response == Gtk.ResponseType.OK: 37 print("Open clicked") 38 print("File selected: " + dialog.get_filename()) 39 elif response == Gtk.ResponseType.CANCEL: 40 print("Cancel clicked") 41 42 dialog.destroy() 43 44 def add_filters(self, dialog): 45 filter_text = Gtk.FileFilter() 46 filter_text.set_name("Text files") 47 filter_text.add_mime_type("text/plain") 48 dialog.add_filter(filter_text) 49 50 filter_py = Gtk.FileFilter() 51 filter_py.set_name("Python files") 52 filter_py.add_mime_type("text/x-python") 53 dialog.add_filter(filter_py) 54 55 filter_any = Gtk.FileFilter() 56 filter_any.set_name("Any files") 57 filter_any.add_pattern("*") 58 dialog.add_filter(filter_any) 59 60 def on_folder_clicked(self, widget): 61 dialog = Gtk.FileChooserDialog( 62 title="Please choose a folder", 63 parent=self, 64 action=Gtk.FileChooserAction.SELECT_FOLDER, 65 ) 66 dialog.add_buttons( 67 Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, "Select", Gtk.ResponseType.OK 68 ) 69 dialog.set_default_size(800, 400) 70 71 response = dialog.run() 72 if response == Gtk.ResponseType.OK: 73 print("Select clicked") 74 print("Folder selected: " + dialog.get_filename()) 75 elif response == Gtk.ResponseType.CANCEL: 76 print("Cancel clicked") 77 78 dialog.destroy() 79 80 81win = FileChooserWindow() 82win.connect("destroy", Gtk.main_quit) 83win.show_all() 84Gtk.main()