SECTIONS
Sections
What is it
Requirements
More detail
Install
Usage
Status
Bug reports / Feedback
Copyright
Thanks
WHAT IS IT
GTK+ is a feature-full widget set toolkit for X11 (and windows in the future). Glade is a RAD-style UI builder for GTK+. Python is an interpreted, object-oriented language for which it is very easy to write extensions as "library modules". PyGtk is one such extension, that provide python access to GTK+.
Glade is written to generate code that builds the specified user interface, and can do it for several target languages, but alas not Python.
gladepyc bridges this gap between python and glade, by translating XML contents of glade save files to python code. The generated python code uses the low-level layer of PyGtk (raw C API, non-object-oriented functions) to build the desired user interface.
REQUIREMENTS
Python is needed at "compile"-time. I used to work with version 1.5.1
and now use 1.5.2.
PyGtk is needed at runtime. Version 0.6.8 is now required.
Glade is needed if you want to design interfaces ! I currently use
0.5.11; All the 0.5.x series should be ok, and 0.4.x might be too
though I have not tested since very long. Glade 0.6.x has not been
tested -- yet.
MORE DETAIL
Class based generation:
The generated code is shaped as a module and classes, each class representing a window (default behavior) or a subtree of the user interface. It is then possible at run-time to build as many instances as you want of each class.
- Signals
Signals are delivered in the python object-oriented way. When instanciating a class, you can (optionally) specify a "listener", which methods will be connected to the signals for which the "handler name" corresponds. With this mechanism, 2 windows of the same class can be connected to either same or different listeners.
Those listeners are called "user interface controllers" in the user interface theory (this is often called the Model-View-Controller model). Traditionally there is only one, main, controller that could be called "the application".
Gladepyc goes one step further and encourages the implementation of hierarchical controllers, where each window (or possibly a widget subtree) has its own sub-controller (and thus its own state), and each sub-controller is attached to a main controller (or possibly another sub-controller). The controller at the top of the hierarchy can then be arguably considered as the application's controller.
Anyway if you just want to stay with the traditional model, nothing prevents it: simply always specify the same controller when instanciating classes. What matters here is you are free to do as you want.
Maybe you have guessed listeners are classes, because they are tested for "methods" to connect to. Actually, it can also be a bare module, or any object that simulates the right attribute names (i.e. if you pass "foo" as listener, and a signal needs to be connected to "bar", then you need "foo.bar" to work to have the signal connected); This way you can use simple functions as signal callbacks, just as in C.
Getting and setting user interface data:
In each generated widget tree there will be interface components holding applicative data. It rapidly becomes tedious to write the underlying toolkit calls to fetch and set those data in the components.
gladepyc is able to generate get and set methods that fetch and set those data all at a time from/to a python object, such that data holded by a component will be available in the object as an attribute with the name of that component. Note that radio buttons and menu items are handled gracefully as a single attribute with the name of the radio group.
Those methods are attached to a generated data class of the same name as the class on which they operate (with the "Data" suffix so that class names don't clash).
Alternatively, gladepyc can generate those get/set methods in the widget tree building class, with one couple of methods per UI component. This may be simpler for some uses than a separate data-holding object, but the drawback is that one call must be made per component to get or set, so this is best suited to small forms.
Foreign widgets incorporation
Through the use of glade's custom widget, it is possible to add to an interface a widget coming from another module. The widget can be a true Gtk widget coming from a native module (example: gtkhtml), or another gladepyc generated UI building class.
Automatic controllers
Since version 1.1, UI building classes can be setup, to automatically make a new controller instance and connect to it when they are created.
Let's say you've got a window "myWin", that is translated by gladepyc into an UI building class of the same name. All you have to do is change a class attribute to point a class that instanciates without arguments, and a new controller instance will be created (and connected to) each time you create a new "myWin". For example, we write a very simple controller that handles quitting the application:
class myApp :
def quit (self, *args) :
gtk_main_quit ()
def loadData (self) :
...
Then to make a new window we write:
myWin.controllerClass = myApp
w = myWin ()
gtk_main ()
Within callback methods the instanciated controller is stored in the "controller" instance attribute:
w.controller.loadData ()
Interoperability with PyGtk
If you want or need to use the high-level API of PyGtk, you can do so, as with any GtkObject you have in hand, by creating a high-level object bound to the low-level one with the _obj2inst() function, like this:
w = gtk.gtksomething_new ()
wObj = gtk._obj2inst (w)
This will automatically recognize the object's type, and create an object of the corresponding high-level class, if it is known to PyGtk.
Support routines
The code generated by gladepyc needs a few functions and methods to accomplish its work: some widget building operations and get/set methods for some widgets are quite complex, so they have been factorized into the "support module" to gain maintainability. This was very small at start of gladepyc development, and has now grown to a few kilobytes.
Actually this module is by default incorporated into the generated code, but options exist to request that it is written to a separate file, or even not written at all but instead only imported in the generated code.
Internationalization (I18n)
(actually Automatic Messages Translation)
From version 1.3 on, gladepyc honors the "gettext support" checkbox in project options: Strings subject to translation, are recorded in a text file beside the output module; This file is called a message file or catalog.
Message catalog files reside in the same directory as the output UI module (i.e. the one specified with "-o"), and have the name
<program name>-<language id>.txt where <program name> is the one specified in Glade project options (if you let it empty, the project name is considered instead), and <language id> is a code as found in LC_*/LANG environment variables, such as "C", "fr", or "fr_FR".
The language "C" is always available. The corresponding file is automatically written by gladepyc, and contains strings used during UI design (the name "C" relates to the fact that we use the actual implementation).
To write a new translation for a program "foo" and language "fr", simply copy the file "foo-C.txt" to "foo-fr.txt" and edit it:
- edit each right-side string; Note that Python string representation is used and must be retained; In particular, line breaks are coded with \n, tabulations with \t or \011, and backslashes and quotes must be protected with \.
- you can use "+X" as a line by itself to include the message catalog for language X at the point the line appears. Use it for example to include a basic language from a regional one (e.g. include "fr" from "fr_FR", "fr_BE" and "fr_CA"). You need not use "+C", as the native version of strings is recorded in the generated code. Be aware that when you use this, the included file MUST exist at run-time, or you will get an exception.
When it is time to update a translation file, you can use the following unix commands:
# remove any line starting with "+" from both files
# (it would confuse the join command)
join -v1 -t'\t' foo-C.txt foo-fr.txt > foo-fr.add
# note \t must be typed as <Ctrl-V><TAB>
which gives the strings found in "C" but not in "fr", and records them in file "foo-fr.add". You can edit this file, then use
sort foo-fr.txt foo-fr.add > foo-fr.new
mv foo-fr.new foo-fr.txt
# edit foo-fr.txt to put back any line starting with "+"
# that you have removed at first.
to merge new strings in the definitive catalog.
INSTALL
make install [prefix=/usr/local]
USAGE
gladepyc --help
gladepyc mygui.glade -o mygui.py
gladepyc mygui.glade -o mygui.py --with-getset
STATUS
Status and change information is now located in the NEWS file.
BUG REPORTS / FEEDBACK
Feel free to mail me at fcoutant@freesurf.fr .
I will particularly appreciate if you explain any difficulties you have, but also whether it works and/or is useful for you.
COPYRIGHT
This software is copyright (c)2000 F.COUTANT. It is placed under the GPL license.
THANKS
Many thanks to authors of the following projects (and contributors to those respective projects) for making available such a great development environment !
Python (Guido VON ROSSUM),
PyGtk (James HENSTRIDGE),
Gtk+,
Glade (Damon CHAPLIN)
