Dialogues
| Anke (encarsia) | Also available in: Deutsch
Contents
Handle dialogue windows
Dialogues are complementary windows which are useful in interaction with the user, to show some relevant information or demand input. The GtkDialog class provides subclasses for common dialogue use cases like the AboutDialog and MessageDialog used in the example file. (FileChooserDialog article).
Glade
In the widget sidebar dialog widgets are integrated to the "Toplevel" section next to window widgets.
Dialogs are complementary windows to grab the user's focus. They can fixed to a superordinated window but at least be configured transient to a parent window via General > Window Attributes Transient For:".
AboutDialog
The "About" dialog window in general gives information about the project, its version, license, participating programmers, translators etc. All this can be directly typed into Glade.
MessageDialog
The MessageDialog is a standard dialog to show information or call for input. It is configurated to be drawn without window decoration or showing up seperately in the taskbar. Furthermore there is the possibility to add standard buttons.
Buttons and responses
Dialogs already own an intern GtkButtonBox to place any buttons in.
In constrast to regular windows the clicked signals of the buttons do not have to be assigned in these Buttonboxes (it's still possible to do so, of course). Instead in the "General" button properties you define a response answer (int) and assign the response signal of the GtkDialog.
Standard buttons available for example in MessageDialogs have a fixed response (see also Python GI API Reference):
Ok -5
Abort -6
Close -7
Yes -8
No -9
[X] -4
The huge advantage of that procedure is that the response refers to the dialog object so the responses can be processed by a single function.
Reestablish dialogues
The problem of windows closed via destroy signal is that they cannot be reactivated therefore the delete-event signal is used here.
Python
Responses
When emitting the response signal the response is passed as parameter. As said before this offers the option to process all responses in one function:
def on_dialog_response(self,widget,response): if response == 0: widget.hide_on_delete() elif response == 1: do.something() elif response == (2 or 3): do.something.different()
Delete-event
The hide_on_delete()
function removes a window but can be reestablished by show_all()
:
def on_dialog_delete_event(self,widget,event): widget.hide_on_delete() return True
Several Glade files
As mentioned before several Glade files can be used within a project. It is not possible though to associate dialogs with their parent window if separated into different files. So the set_transient_for
function of GtkWindow is required:
dialog.set_transient_for(mainwindow)
Listings
Glade
<?xml version="1.0" encoding="UTF-8"?> <!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.20"/> <object class="GtkApplicationWindow" id="window"> <property name="can_focus">False</property> <property name="title" translatable="yes">Titel</property> <signal name="destroy" handler="on_window_destroy" swapped="no"/> <child type="titlebar"> <placeholder/> </child> <child> <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> <child> <object class="GtkButton" id="aboutbutton"> <property name="label" translatable="yes">GtkAboutDialog</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <signal name="clicked" handler="on_aboutbutton_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkButton" id="messagebutton"> <property name="label" translatable="yes">GtkMessageDialog</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <signal name="clicked" handler="on_messagebutton_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> </child> </object> <object class="GtkAboutDialog" id="aboutdialog"> <property name="can_focus">False</property> <property name="type_hint">dialog</property> <property name="transient_for">window</property> <property name="attached_to">window</property> <property name="program_name">Glade-Tutorial</property> <property name="version">1.0</property> <property name="logo_icon_name">help-about</property> <property name="license_type">mit-x11</property> <signal name="delete-event" handler="on_dialog_delete_event" swapped="no"/> <signal name="response" handler="on_dialog_response" swapped="no"/> <child type="titlebar"> <placeholder/> </child> <child internal-child="vbox"> <object class="GtkBox"> <property name="can_focus">False</property> <property name="orientation">vertical</property> <property name="spacing">2</property> <child internal-child="action_area"> <object class="GtkButtonBox"> <property name="can_focus">False</property> <property name="layout_style">end</property> <child> <object class="GtkButton" id="button1"> <property name="label">gtk-ok</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="use_stock">True</property> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">0</property> </packing> </child> </object> </child> <action-widgets> <action-widget response="-8">button1</action-widget> </action-widgets> </object> <object class="GtkMessageDialog" id="messdialog"> <property name="can_focus">False</property> <property name="type_hint">dialog</property> <property name="transient_for">window</property> <property name="buttons">yes-no</property> <property name="text" translatable="yes"><b>MessageDialog schließen?</b></property> <property name="use_markup">True</property> <signal name="response" handler="on_dialog_response" swapped="no"/> <child type="titlebar"> <placeholder/> </child> <child internal-child="vbox"> <object class="GtkBox"> <property name="can_focus">False</property> <property name="orientation">vertical</property> <property name="spacing">2</property> <child internal-child="action_area"> <object class="GtkButtonBox"> <property name="can_focus">False</property> <property name="homogeneous">True</property> <property name="layout_style">end</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">0</property> </packing> </child> </object> </child> </object> </interface>
Python
#!/usr/bin/python # -*- coding: utf-8 -*- import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk class Handler: def on_window_destroy(self, *args): Gtk.main_quit() def on_dialog_delete_event(self, widget, event): widget.hide_on_delete() return True def on_aboutbutton_clicked(self, widget): x.obj("aboutdialog").run() def on_messagebutton_clicked(self, widget): x.obj("messdialog").format_secondary_text("") x.obj("messdialog").run() def on_dialog_response(self, widget, response): if response == -8: widget.hide_on_delete() elif response == -9: widget.format_secondary_text("Doch!") class Example: def __init__(self): builder = Gtk.Builder() builder.add_from_file("13_dialoge.glade") builder.connect_signals(Handler()) self.obj = builder.get_object self.obj("window").show_all() def main(self): Gtk.main() x = Example() x.main()
Comments
Comments powered by Disqus