So, working to get away from WX as my main GUI source and using GTK as I’ve been an Ubnutu, then Mint user with Gnome for years. Building windows in Glade3 was not too bad and the rapid prototyping with Python makes it a great tool. Sadly, the documentation for PyGTK 3 does not exist. There are differences yet the examples that are found are all for PyGTK 2. Don’t believe me? Try finding information on drawing to a window. Most notable difference is the use of Cairo instead of GDK but it just starts there. Anyhow, just venting on what should be a great set up which is made difficult by the lack of documentation.
Being an avid Ubuntu user, I wanted to tinker in building for the Gnome interface. An applet was the perfect idea but a tutorial on the internet was hard to find. I found a few like these that are in C, which I’m fond of C but for rapid development and tinkering, Python works much better. Besides, that is my primary programming language and kindly, Ubuntu came with all the required modules to build in this way. Most tutorials for Python were out of date. One of the best I found in Python was this one and my personal favorite which shows a good use of classes.
Onto the tutorial!
The first thing you need to do is build a server file. This will go to /usr/lib/bonobo/servers with root access. The reason for this file is for Gnome to be able find your file and set it as an applet. The lines to pay attention to are:Line 4: This is the full path to your source code file. Lines 9-10: Name and describe your applet. Line 20-23: These are the options you can set for the applet browser.
<oaf_info> <oaf_server iid="OAFIID:SampleApplet_Factory" type="exe" location="/home/zbert/Desktop/testing/py/applet.py"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:Bonobo/GenericFactory:1.0"/> <item value="IDL:Bonobo/Unknown:1.0"/> </oaf_attribute> <oaf_attribute name="name" type="string" value="Sample Applet Factory"/> <oaf_attribute name="description" type="string" value="Sample Applet's Factory that launches the applet"/> </oaf_server> <oaf_server iid="OAFIID:SampleApplet" type="factory" location="OAFIID:SampleApplet_Factory"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/Vertigo/PanelAppletShell:1.0"/> <item value="IDL:Bonobo/Control:1.0"/> <item value="IDL:Bonobo/Unknown:1.0"/> </oaf_attribute> <oaf_attribute name="name" type="string" value="Sample Applet"/> <oaf_attribute name="description" type="string" value="Sample applet's description."/> <oaf_attribute name="panel:category" type="string" value="Utility"/> <oaf_attribute name="panel:icon" type="string" value="gnome-laptop.png"/> </oaf_server> </oaf_info>
#!/usr/bin/env python ### NORMAL IMPORTS import sys import gtk import pygtk import gnomeapplet pygtk.require('2.0') ### CREATE A MENU WITH XML def create_menu(applet): xml = """ <popup name="button3"> <menuitem name="Item 1" verb="Networks" label="_Networks...." pixtype = "stock" pixname="gtk-properties"/> <menuitem name="Item 2" verb="Help" label="_Help" pixtype = "stock" pixname="gtk-help"/> <separator/> <menuitem name="Item 3" verb="About" label="_About..." pixtype = "stock" pixname="gnome-stock-about"/> </popup> """ verbs = [('Networks',show_networks), ('Help',show_help), ('About',show_about)] applet.setup_menu(xml, verbs, None) ### WHAT HAPPENS WHEN MENU ITEM IS CLICKED def show_about(*arguments): print(arguments) ### THE ASTERIK ALLOWS MULTIPLE ARGUMENTS TO BE PASSED def show_networks(*arguments): print(arguments) ### ALL OF THESE SHOW IN THE DEBUG (-d) OPTION def show_help(*arguments): print(arguments) ### WHERE IT ALL HAPPENS def applet_factory(applet, iid): # CREATE THE XML MENU create_menu(applet) # CREATE AN IMAGE OBJECT im = gtk.Image() # SET THE FILE FOR THE IMAGE im.set_from_file("/home/zbert/Desktop/testing/py/face2.png") # ENABLE TRANSPARENCY applet.set_background_widget(applet) # CREATE AN EVENT FOR CLICKING THE IMAGE applet.connect('button-press-event',button_press) # ADD IT ALL TO THE APPLET applet.add(im) # SHOW IT! applet.show_all() # DEBUG EVENT print('Factory started') return True ### CREATE A DIALOG TO POP UP WHEN APPLET IS CLICKED def test(*arguments): print(arguments) dia = gtk.Dialog("Message",None,gtk.DIALOG_MODAL) lbl = gtk.Label("this is a message") dia.vbox.pack_start(lbl) lbl.show() dia.run() dia.connect("destroy",dia.destroy) ### HANDLE THE IMAGE CLICK def button_press(button, event): # LEFT BUTTON ACTIVATES THE CUSTOM MENU if event.button == 1: print "button 1" # CREATE A CUSTOM MENU m = gtk.Menu() i = gtk.MenuItem("Hello") i.show() # CONNECT THIS MENU ITEM TO THE DIALOG i.connect("activate",test,"Hello") m.append(i) # FINISH THE POPUP MENU m.popup(None, None, None, event.button, event.time, None) # RIGHT BUTTON ACTIVATES THE STANDARD MENU elif event.button == 2: # DEBUG print "button 2" ### STANDARD ENTRY if __name__ == '__main__': # DEBUG print('Starting factory') # RUN THE APPLET AS A GTK WINDOW IN DEBUG (-d) MODE if len(sys.argv) > 1 and sys.argv == '-d': # mainWindow = gtk.Window() mainWindow.set_title('Applet window') mainWindow.connect('destroy',gtk.main_quit) applet = gnomeapplet.Applet() applet_factory(applet, None) applet.reparent(mainWindow) mainWindow.show_all() gtk.main() sys.exit() # LET GNOME TAKE CARE OF IT AS AN APPLET else: gnomeapplet.bonobo_factory('OAFIID:SampleApplet_Factory', gnomeapplet.Applet.__gtype__, 'Sample Applet', '0.1', applet_factory)
You can see in these pictures how the applet sits like any other in the corner. A left click will bring up our custom coded menu with one selection, ‘Hello’ which when clicked brings up a GTK Dialog that is made in the button_press() event. If you right click, you get the standard menu, plus our XML menu which, when in Debug (-d) mode, you will see the arguments sent by a click outputted in your terminal. As I mentitoned, there are a handful of great resources for this that detail current Python modules with information on setting this up as I did or in a class for bigger projects. I hope this tutorial has been helpful, and let me know what you think of these lessons with the comments interface!
So for anyone reading this blog, I am still here, just have not added anything this week. I’m working and have not been able to update the blog but I will soon have links and information to my linux Cribbage game. This is near completion and I have written it using pygtk. It is using card and game modules that I had designed for a text based run of the program and figuring no one would want to use the text based, I’ve switched to a GTK interface, which is obviously, much better.