Wednesday, March 21, 2007

Custom PyGTK Widgets in Glade3

Glade 3, GTK User Interface Designer is really quite nice since release 3.1, since it does away with the gimp-like multi-window view and looks like a normal application. Another nice feature it has is being able to support widgets created in non-C (in our case PyGTK).

Components of a plugin:
  1. A catalog file
  2. A support module
  3. Some icon pixmaps (optional)
We shall use, for our example, the Kiwi Hyperlink widget, (which I wrote). This widget is an EventBox subclass, so we shall illustrate turning off some of the additional properties that are not required in the user interface designer.

The catalog file



This is described in http://glade.gnome.org/docs/catalogintro.html and the subsequent pages of the documentation. Essentially there are two sections of the catalog:
  1. The Widget definitions
  2. The Catalog list
The Widget Definitions are like so:


<glade-widget-classes>
<glade-widget-class title="Hyper Link" name="HyperLink" />
</glade-widget-classes>


These are the most-often used attributes for the widget class, but there are a few others too that are outlined on the documentation page.

The catalog listing is much more basic, and less variable, and takes the following form:


<glade-widget-group name="KiwiWidgets" title="Kiwi Widgets">
<glade-widget-class-ref name="HyperLink"/>


This lists all the widgets that are currently available. So far we have not strayed from the documentation, and this is exactly how you would add widgets that are non-PyGTK.

What you have to do to make glade realise that you are using PyGTK widgets is use this in your main document element for the catalog:


<glade-catalog name="kiwiwidgets" library="kiwiwidgets" domain="glade-3" depends="gtk+" language="python">


The language="python" does that for you, and in addition the library attribute "kiwiwidgets" defines the location of our support library, which will be called kiwiwidgets.py.

The catalog file should live with the other catalogs in the glade3 catalog directory, which is, on my system, at:

/usr/local/share/glade3/catalogs/kiwiwidgets.xml


You can turn various properties off from being displayed in the user interface designer using the <properties> tag in your widget-class tag. An example of this would be:


<property id="visible-window"
visible="False" />
<property id="text"
name="Text"
translatable="True" />


Ok, so we showed you two properties here. The first is a property of Event Box which we don't want shown inside the UI Designer (users don't care), and that is achieved with a simple visible="False". The second shows how to modify a property. We want the text of this hyperlink widget to be translatable, and access all the translation hooks in Glade with it.


The support module



The support module is python code that goes with our widgets. In our basic example, we have not defined anything fancy like a custom adaptor, or even a custom editor which we could if we were feeling brave, but will probably leave that for another blog posting.

The support module should live in the glade module directory, and be named as defined in the catalog file. On my system this belongs here:

/usr/local/lib/glade3/modules/kiwiwidgets.py


the code of the module in this simple case contains only one thing, an import statement on the HyperLink class (since that is all that is needed to register it as a GObject Type.


from kiwi.ui.hyperlink import HyperLink


Glade3 takes care of the rest for us.

That is all for now. Other items that should come up later include:

  • Defining custom adaptors
  • Defining custom widget editors
  • Silencing glade queries for box subclasses
  • Controlling the glade UI from Python
And I shall address these if there is any interest.

NB: The API is early and changing at this stage, and there is no emphasis on backward-compatibility, so be prepared to throw any code away!

11 comments:

orbit7 said...

Hi,
great tutorial/blog! , but i had 2 problems:

1:I had to add a __gtype_name__ attribute to my class to get it imported by glade.

2:without na generic-name in the xml glade won't show a (default) icon.

==my_widgets.py:
import gtk
class MyButton(gtk.Button):
__gtype_name__ = 'MyButton'

==my_widgets.xml (replaced <> with [])
[glade-catalog name="My Widgets" library="my_widgets" domain="glade-3" depends="gtk+" language="python"]
[glade-widget-classes]
[glade-widget-class title="MyButton" name="MyButton" generic-name="mybutton"/]
[/glade-widget-classes]
[glade-widget-group name="my_widgets" title="my_widgets"]
[glade-widget-class-ref name="MyButton"/]
[/glade-widget-group]
[/glade-catalog]

Polaris said...

The code is good but i would have preferred to see a custom adaptor for the widgets, I have never actually used python so I love this stuff especially when im learning something new,

Simon Tully said...

Python is a great basis for this type of application and code, I wrotr code for a wholesale lists company and it was perfect for the job.

Michael said...

While working for a known company I used python to write some of the code for an application that is used by a Teletext Flights company, it was not my first choice and I did not feel it was totally right for the job so I used the .net framework to complete it.

Anonymous said...

HI,

We are following your tutorial in order to add a custom widget to Glade-3. We have generated a catalogue file (.xml) and added it to Glade3/catalogs, and copied the module file to Glade3/modules. But when starting Glade3 we get the following error:

(glade-3:3020): GladeUI-CRITICAL **: Unable to load module 'vtkwidgets' from any search paths

in spite of the fact that we have added this location to our PATH, LD_LIBRARY_PATH and PYTHONPATH. Do you have any idea why this may be?

Cheers then!

Ali said...

I believe this method has been depracated in recent versions of glade3. 3.0 Should work fine, and I think they are working on a new, better way to achieve it.

Alex said...
This post has been removed by a blog administrator.
Mike Machenry said...

Warning to the user: it appears as if the functionality in glade that supports Python custom widgets has been removed and this tutorial won't work unless you get the right branch of the code from CVS. Here's my reference for that:

http://lists.ximian.com/pipermail/glade-users/2007-December/003731.html

-mike

Anonymous said...

Hi

Seems to work again in latest versions of glade-3. You also need something like:

[init-function]glade_python_init[/init-function]

inside [glade-catalog]

You can find full example within the kiwi project (full catalog and module files).

Grtz.

Anonymous said...

and for the record, by latest i mean svn as of 6-03-2009, and 3.5.7 too (ubuntu jaunty version at this moment -still alpha-).

armyshop said...

I am new with python. I need it for my work. I was not able to put a custom widget to glade3. I only get error messages...