Stand-alone
| Anke (encarsia) | Also available in: Deutsch
Contents
Run program as GtkApplication
GtkApplication handles different important aspects of a GTK+ application like GTK+ initialization, session management and desktop integration.
XML files
Glade
Glade is used as usual, main windows should be Gtk.ApplicationWindows. As example the file from the dialogue article is reused.
Python
Initialize GtkApplication
The initialization process requires the parameters application_id and flags. Flags can normally set to 0 being the same as FLAGS_NONE (see Gio.ApplicationFlags), naming conventions for application_id are listed here.
The application can be connected to different signals being emitted on preassigned events. It is mandatory to at least define an activate
signal:
def __init__(self): self.app = Gtk.Application.new("org.application.test", 0) #self.app.connect("startup", self.on_app_startup) #optional self.app.connect("activate", self.on_app_activate) #self.app.connect("shutdown", self.on_app_shutdown) #optional def on_app_activate(self, app): #setting up GtkBuilder etc. ... ... ...
Start and quit
GtkApplication takes over the handling of the GTK+ mainloop so there is no need of starting and quitting GTK+ manually and run()
and quit()
called instead:
Gtk.main() -> app.run(argv) Gtk.main_quit() -> app.quit()
If the application is quit by the [X] button or the "Quit" appmenu entry the "shutdown" signal is emitted (see above) and the program is terminated. That means there is no need to define these signals like in previous examples using GtkWindow. The "shutdown" also works even if the signal is not explicitly connected to a function during the initialization process.
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>
GMenu
<?xml version="1.0"?> <interface> <menu id="appmenu"> <section> <item> <attribute name="label" translatable="yes">About</attribute> <attribute name="action">app.about</attribute> </item> <item> <attribute name="label" translatable="yes">Message</attribute> <attribute name="action">app.message</attribute> </item> </section> <section> <item> <attribute name="label" translatable="yes">Quit</attribute> <attribute name="action">app.quit</attribute> <attribute name="accel"><Primary>q</attribute> </item> </section> </menu> </interface>
Python
#!/usr/bin/python # -*- coding: utf-8 -*- import sys import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk, Gio class Handler: def on_window_destroy(self,window): window.close() def on_dialog_delete_event(self,widget,event): widget.hide_on_delete() return True def on_aboutbutton_clicked(self,widget): app.obj("aboutdialog").show_all() def on_messagebutton_clicked(self,widget): app.obj("messdialog").format_secondary_text("") app.obj("messdialog").show_all() def on_dialog_response(self,widget,response): if response == -8: widget.hide_on_delete() elif response == -9: widget.format_secondary_text("Doch!") class ExampleApp: def __init__(self): self.app = Gtk.Application.new("org.application.test", Gio.ApplicationFlags(0), ) self.app.connect("startup", self.on_app_startup) self.app.connect("activate", self.on_app_activate) self.app.connect("shutdown", self.on_app_shutdown) def on_app_startup(self, app): print("Gio.Application startup signal emitted") def on_app_activate(self, app): print("Gio.Application activate signal emitted") builder = Gtk.Builder() builder.add_from_file("13_dialoge.glade") builder.add_from_file("14_giomenu.ui") builder.connect_signals(Handler()) app.set_app_menu(builder.get_object("appmenu")) self.obj = builder.get_object self.obj("window").set_application(app) # display application name in upper panel of the GNOME Shell (deprecated) # self.obj("window").set_wmclass("Application test","Application test") self.obj("window").show_all() self.add_simple_action("about", self.on_action_about_activated) self.add_simple_action("message", self.on_action_message_activated) self.add_simple_action("quit", self.on_action_quit_activated) def on_app_shutdown(self, app): print("Gio.Application shutdown signal emitted") def add_simple_action(self, name, callback): action = Gio.SimpleAction.new(name) action.connect("activate", callback) self.app.add_action(action) def on_action_about_activated(self, action, user_data): self.obj("aboutdialog").show_all() def on_action_message_activated(self, action, user_data): Handler().on_messagebutton_clicked(self) def on_action_quit_activated(self, action, user_data): self.app.quit() def run(self, argv): self.app.run(argv) app = ExampleApp() app.run(sys.argv)
Comments
Comments powered by Disqus