GNOME application development
Summary
A beginner’s guide to GNOME 3 application
development
David King <
[email protected]>
23rd May 2014 / GNOME.Asia / #8 conference room
Licensed under CC0-1.0
TM
GNOME application development
Summary
Overview
GNOME as a platform for
application development
6-month development
cycle
write applications in
Python, JavaScript, Vala or
C
TM
GNOME application development
Summary
Platform libraries
GLib (including GObject
and GIO)
GTK+
many others (see the
application development
overview on
developer.gnome.org)
TM
GNOME application development
Summary
Development tools
Glade, for designing GUIs
Devhelp, for browsing API reference
documentation
Anjuta, an integrated development
environment (IDE)
Builder, a future GNOME IDE
Inspector, a GTK+ tool for debugging
UIs
TM
GNOME application development
Summary
Before we start
Clone the git repository: git clone
git://fedorapeople.org/home/fedora/amigadave/
public_git/python-gnome-app.git
Browse through the git commits:
http://fedorapeople.org/cgit/amigadave/
public_git/python-gnome-app.git/
Open your favourite text editor or IDE
Try running the application: ./python-gnome-app
TM
GNOME application development
Summary
Hello world!
Import GObject-Introspection
Show a window
Run the GTK+ main loop
The application must be killed externally!
TM
GNOME application development
Summary
Hello world code
# ! / u s r / b i n / python3
from g i . r e p o s i t o r y import Gtk
window = Gtk . Window ( )
window . s h o w _ a l l ( )
Gtk . main ( )
TM
GNOME application development
Summary
Signals and handlers
Subclass (inherit) GtkApplication
Connect the activate signal of the application to a
handler
Create or show the window in the handler
GTK+ widgets (and other GObjects) have signals, which
are documented in the API references
The application terminates when the window is closed
See https://wiki.gnome.org/HowDoI/GtkApplication for
more details on GtkApplication
TM
Signals and handlers code 1
# ! / u s r / b i n / python3
import sys
from g i . r e p o s i t o r y import Gtk
class PythonApp ( Gtk . A p p l i c a t i o n ) :
def _ _ i n i t _ _ ( s e l f ) :
Gtk . A p p l i c a t i o n . _ _ i n i t _ _ (
self ,
a p p l i c a t i o n _ i d = " org . example . PythonGnome " )
s e l f . connect ( " a c t i v a t e " , s e l f . o n _ a c t i v a t e )
def o n _ a c t i v a t e ( s e l f , app ) :
window = Gtk . ApplicationWindow ( a p p l i c a t i o n =app )
window . s h o w _ a l l ( )
# Continued on n e x t s l i d e .
GNOME application development
Summary
Signals and handlers code 2
# Continued from p r e v i o u s s l i d e .
app = PythonApp ( )
e x i t _ s t a t u s = app . run ( None )
sys . e x i t ( e x i t _ s t a t u s )
TM
GNOME application development
Summary
Keybindings and actions
Add an action for quitting the application, and another for
printing hello world
Connect the activate signal of the actions to handlers
Add an accelerator to each action
See https://wiki.gnome.org/HowDoI/GAction for more
details
TM
Keybindings and actions code 1
# ! / u s r / b i n / python3
import sys
from g i . r e p o s i t o r y import Gio , Gtk
class PythonApp ( Gtk . A p p l i c a t i o n ) :
def _ _ i n i t _ _ ( s e l f ) :
Gtk . A p p l i c a t i o n . _ _ i n i t _ _ (
s e l f , a p p l i c a t i o n _ i d = " org . example . PythonGnome " )
s e l f . connect ( " a c t i v a t e " , s e l f . o n _ a c t i v a t e )
s e l f . connect ( " s t a r t u p " , s e l f . o n _ s t a r t u p )
def o n _ s t a r t u p ( s e l f , app ) :
s e l f . window = Gtk . ApplicationWindow ( a p p l i c a t i o n =app )
h e l l o _ w o r l d = Gio . S i m p l e A c t i o n (
name= " h e l l o −w o r l d " , parameter_type =None )
s e l f . a d d _ a ct i o n ( h e l l o _ w o r l d )
# Continued on n e x t s l i d e .
Keybindings and actions code 2
# Continued from p r e v i o u s s l i d e .
s e l f . add_accelerator (
" <Primary >h " , " app . h e l l o −w o r l d " , None )
h e l l o _ w o r l d . connect ( " a c t i v a t e " , s e l f . o n _ h e l l o _ w o r l d )
q u i t = Gio . S i m p l e A c t i o n (
name= " q u i t " , parameter_type =None )
s e l f . a d d _ a ct i o n ( q u i t )
s e l f . a d d _ a c c e l e r a t o r ( " <Primary >q " , " app . q u i t " , None )
q u i t . connect ( " a c t i v a t e " , s e l f . o n _ q u i t )
def o n _ a c t i v a t e ( s e l f , app ) :
s e l f . window . s h o w _ a l l ( )
def o n _ h e l l o _ w o r l d ( s e l f , a c t i o n =None , param=None ) :
print ( " Hello world ! " )
def o n _ q u i t ( s e l f , a c t i o n =None , param=None ) :
self . quit ()
# Continued on n e x t s l i d e .
Keybindings and actions code 3
# Continued from p r e v i o u s s l i d e .
app = PythonApp ( )
e x i t _ s t a t u s = app . run ( None )
sys . e x i t ( e x i t _ s t a t u s )
GNOME application development
Summary
Application menus
Create a menu model
Link the menu items to actions, in the correct group
Set the application menu on the application
See https://wiki.gnome.org/HowDoI/ApplicationMenu for
more details
TM
Application menus code 1
# ! / u s r / b i n / python3
import sys
from g i . r e p o s i t o r y import Gio , Gtk
class PythonApp ( Gtk . A p p l i c a t i o n ) :
def _ _ i n i t _ _ ( s e l f ) :
Gtk . A p p l i c a t i o n . _ _ i n i t _ _ (
s e l f , a p p l i c a t i o n _ i d = " org . example . PythonGnome " )
s e l f . connect ( " a c t i v a t e " , s e l f . o n _ a c t i v a t e )
s e l f . connect ( " s t a r t u p " , s e l f . o n _ s t a r t u p )
def o n _ s t a r t u p ( s e l f , app ) :
s e l f . window = Gtk . ApplicationWindow ( a p p l i c a t i o n =app )
h e l l o _ w o r l d = Gio . S i m p l e A c t i o n (
name= " h e l l o −w o r l d " , parameter_type =None )
s e l f . a d d _ a ct i o n ( h e l l o _ w o r l d )
# Continued on n e x t s l i d e .
Applications menus code 2
# Continued from p r e v i o u s s l i d e .
s e l f . add_accelerator (
" <Primary >h " , " app . h e l l o −w o r l d " , None )
h e l l o _ w o r l d . connect ( " a c t i v a t e " , s e l f . o n _ h e l l o _ w o r l d )
q u i t = Gio . S i m p l e A c t i o n (
name= " q u i t " , parameter_type =None )
s e l f . a d d _ a ct i o n ( q u i t )
s e l f . a d d _ a c c e l e r a t o r ( " <Primary >q " , " app . q u i t " , None )
q u i t . connect ( " a c t i v a t e " , s e l f . o n _ q u i t )
appmenu = Gio . Menu . new ( )
s e c t i o n = Gio . Menu . new ( )
h e l l o _ w o r l d _ i t e m = Gio . MenuItem . new (
" H e l l o w o r l d ! " , " app . h e l l o −w o r l d " )
q u i t _ i t e m = Gio . MenuItem . new ( " Q u i t " , " app . q u i t " )
appmenu . append_section ( None , s e c t i o n )
s e c t i o n . append_item ( h e l l o _ w o r l d _ i t e m )
s e c t i o n . append_item ( q u i t _ i t e m )
s e l f . set_app_menu ( appmenu )
# Continued on n e x t s l i d e .
Application menus code 3
# Continued from p r e v i o u s s l i d e .
def o n _ a c t i v a t e ( s e l f , app ) :
s e l f . window . s h o w _ a l l ( )
def o n _ h e l l o _ w o r l d ( s e l f , a c t i o n =None , param=None ) :
print ( " Hello world ! " )
def o n _ q u i t ( s e l f , a c t i o n =None , param=None ) :
self . quit ()
app = PythonApp ( )
e x i t _ s t a t u s = app . run ( None )
sys . e x i t ( e x i t _ s t a t u s )
GNOME application development
Summary
Buttons and actionable widgets
As buttons implement the GtkActionable interface, they
can also be linked to actions
Set the action name on the GtkActionable with the
action-name property
As GtkWindow is a GtkContainer, use the add()
method to put the button in the window
See the GtkActionable API reference for more details
TM
Buttons and actionable widgets code changes
# Put these code l i n e s i n t h e r i g h t p l a c e .
b u t t o n = Gtk . B u t t o n (
l a b e l = " H e l l o w o r l d ! " , action_name= " app . h e l l o −w o r l d " )
s e l f . window . add ( b u t t o n )
GNOME application development
Summary
A simple text editor
Add a GtkEntry (or a GtkTreeView if you are feeling
confident)
Save the contents of the text entry when quitting, load
them on startup
No hints this time, you have to do it yourself!
You will find the GtkEntry API reference helpful. You
should know how to load and save text from a file in Python
TM
GNOME application development
Summary
Deploying your application
Install a desktop file and icon to show your application
alongside others
Use a standard build system to make your application a
releasable unit
Make regular releases, so that your application can be
easily consumed
Package your application for distributions (learn about this
with Fedora at FUDCon)
Look forward to a future of application sandboxing
TM
Example desktop file
[ Desktop ]
Name=My Python App
Comment= S h o r t d e s c r i p t i o n o f t h i s a p p l i c a t i o n
Keywords=python ; e d i t o r ;
Type= A p p l i c a t i o n
Exec=python−gnome−app
I c o n =python−gnome−app
C a t e g o r i e s =Gtk ;GNOME; U t i l i t y ;
Example autotools build system (configure.ac)
AC_INIT ( [ Python GNOME App ] ,
[0.1] ,
[ amigadave@amigadave . com ] ,
[ python−gnome−app ] ,
[ h t t p : / / f e d o r a p e o p l e . org / c g i t / amigadave / p u b l i c _ g i t /
python−gnome−app . g i t / ] )
AM_INIT_AUTOMAKE ( [ 1 . 1 1 f o r e i g n ] )
AC_CONFIG_FILES ( [ M a k e f i l e ] )
AC_OUTPUT
Example autotools build system (Makefile.am)
dist_bin_SCRIPTS = python−gnome−app
desktopdir = $( datadir ) / applications
dist_desktop_DATA = python−gnome−app . desktop
GNOME application development
Summary
Using the autotools build system
Run autoreconf --force --install to generate the
build files
Run ./configure to configure the project and check for
required dependencies
Run make to build the project, and make install to
install it into the default prefix
Run make distcheck to create a tarball and perform a
build and install check
TM
GNOME application development
Summary
Translations
GNOME applications use GNU gettext for marking,
extracting and retrieving translatable strings
intltool is currently used for translating desktop files and
GSettings schemas, but the latest version of gettext can do
this too
See the translation guide in the application development
overview
TM
GNOME application development
Summary
User help
GNOME application documentation is written in the
Mallard format
Designed to be concise and task-based
Attend the “GNOME Documentation” talks for more
information
See the user help section of the application development
overview
TM
GNOME application development
Summary
Further resources
Mailing lists, https://mail.gnome.org/
Wiki, https://wiki.gnome.org/
IRC,
https://wiki.gnome.org/Community/GettingInTouch/IRC
https://developer.gnome.org/
https://python-gtk-3-tutorial.readthedocs.org/en/latest/
TM
Settings management
GSettings is the API in GIO used for storing user
preferences
Settings are stored in dconf on Unix, the registry on
Windows
GAction can be backed by a setting
TM
New widgets
popovers, header bars, and lots more!
See my talk “Bringing your GNOME application up-to-date”
TM