3
Module that provides an object oriented abstraction to pygtk and libglade.
4
Copyright (C) 2004 Sandino Flores Moreno
7
# This library is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU Lesser General Public
9
# License as published by the Free Software Foundation; either
10
# version 2.1 of the License, or (at your option) any later version.
12
# This library is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
# Lesser General Public License for more details.
17
# You should have received a copy of the GNU Lesser General Public
18
# License along with this library; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33
__author__ = 'Sandino "tigrux" Flores-Moreno'
35
def bindtextdomain(app_name, locale_dir=None):
37
Bind the domain represented by app_name to the locale directory locale_dir.
38
It has the effect of loading translations, enabling applications for different
42
a domain to look for translations, tipically the name of an application.
45
a directory with locales like locale_dir/lang_isocode/LC_MESSAGES/app_name.mo
46
If omitted or None, then the current binding for app_name is used.
51
locale.setlocale(locale.LC_ALL, "")
52
gtk.glade.bindtextdomain(app_name, locale_dir)
53
gettext.install(app_name, locale_dir, unicode=1)
54
except (IOError,locale.Error), e:
55
print "Warning", app_name, e
56
__builtins__.__dict__["_"] = lambda x : x
61
def __init__(self, path, root=None, domain=None, **kwargs):
63
Load a glade file specified by glade_filename, using root as
64
root widget and domain as the domain for translations.
66
If it receives extra named arguments (argname=value), then they are used
67
as attributes of the instance.
70
path to a glade filename.
71
If glade_filename cannot be found, then it will be searched in the
72
same directory of the program (sys.argv[0])
75
the name of the widget that is the root of the user interface,
76
usually a window or dialog (a top level widget).
77
If None or ommited, the full user interface is loaded.
80
A domain to use for loading translations.
81
If None or ommited, no translation is loaded.
84
a dictionary representing the named extra arguments.
85
It is useful to set attributes of new instances, for example:
86
glade_app = SimpleGladeApp("ui.glade", foo="some value", bar="another value")
87
sets two attributes (foo and bar) to glade_app.
89
if os.path.isfile(path):
90
self.glade_path = path
92
glade_dir = os.path.dirname( sys.argv[0] )
93
self.glade_path = os.path.join(glade_dir, path)
94
for key, value in kwargs.items():
96
setattr(self, key, weakref.proxy(value) )
98
setattr(self, key, value)
100
self.install_custom_handler(self.custom_handler)
101
self.glade = self.create_glade(self.glade_path, root, domain)
103
self.main_widget = self.get_widget(root)
105
self.main_widget = None
106
self.normalize_names()
107
self.add_callbacks(self)
111
class_name = self.__class__.__name__
113
root = gtk.Widget.get_name(self.main_widget)
114
repr = '%s(path="%s", root="%s")' % (class_name, self.glade_path, root)
116
repr = '%s(path="%s")' % (class_name, self.glade_path)
121
Method called when the user interface is loaded and ready to be used.
122
At this moment, the widgets are loaded and can be refered as self.widget_name
126
def add_callbacks(self, callbacks_proxy):
128
It uses the methods of callbacks_proxy as callbacks.
129
The callbacks are specified by using:
130
Properties window -> Signals tab
131
in glade-2 (or any other gui designer like gazpacho).
133
Methods of classes inheriting from SimpleGladeApp are used as
134
callbacks automatically.
137
an instance with methods as code of callbacks.
138
It means it has methods like on_button1_clicked, on_entry1_activate, etc.
140
self.glade.signal_autoconnect(callbacks_proxy)
142
def normalize_names(self):
144
It is internally used to normalize the name of the widgets.
145
It means a widget named foo:vbox-dialog in glade
146
is refered self.vbox_dialog in the code.
148
It also sets a data "prefixes" with the list of
149
prefixes a widget has for each widget.
151
for widget in self.get_widgets():
152
widget_name = gtk.Widget.get_name(widget)
153
prefixes_name_l = widget_name.split(":")
154
prefixes = prefixes_name_l[ : -1]
155
widget_api_name = prefixes_name_l[-1]
156
widget_api_name = "_".join( re.findall(tokenize.Name, widget_api_name) )
157
gtk.Widget.set_name(widget, widget_api_name)
158
if hasattr(self, widget_api_name):
159
raise AttributeError("instance %s already has an attribute %s" % (self,widget_api_name))
161
setattr(self, widget_api_name, widget)
163
gtk.Widget.set_data(widget, "prefixes", prefixes)
165
def add_prefix_actions(self, prefix_actions_proxy):
167
By using a gui designer (glade-2, gazpacho, etc)
168
widgets can have a prefix in theirs names
169
like foo:entry1 or foo:label3
170
It means entry1 and label3 has a prefix action named foo.
172
Then, prefix_actions_proxy must have a method named prefix_foo which
173
is called everytime a widget with prefix foo is found, using the found widget
176
prefix_actions_proxy:
177
An instance with methods as prefix actions.
178
It means it has methods like prefix_foo, prefix_bar, etc.
181
prefix_pos = len(prefix_s)
183
is_method = lambda t : callable( t[1] )
184
is_prefix_action = lambda t : t[0].startswith(prefix_s)
185
drop_prefix = lambda (k,w): (k[prefix_pos:],w)
187
members_t = inspect.getmembers(prefix_actions_proxy)
188
methods_t = filter(is_method, members_t)
189
prefix_actions_t = filter(is_prefix_action, methods_t)
190
prefix_actions_d = dict( map(drop_prefix, prefix_actions_t) )
192
for widget in self.get_widgets():
193
prefixes = gtk.Widget.get_data(widget, "prefixes")
195
for prefix in prefixes:
196
if prefix in prefix_actions_d:
197
prefix_action = prefix_actions_d[prefix]
198
prefix_action(widget)
200
def custom_handler(self,
201
glade, function_name, widget_name,
202
str1, str2, int1, int2):
204
Generic handler for creating custom widgets, internally used to
205
enable custom widgets (custom widgets of glade).
207
The custom widgets have a creation function specified in design time.
208
Those creation functions are always called with str1,str2,int1,int2 as
209
arguments, that are values specified in design time.
211
Methods of classes inheriting from SimpleGladeApp are used as
212
creation functions automatically.
214
If a custom widget has create_foo as creation function, then the
215
method named create_foo is called with str1,str2,int1,int2 as arguments.
218
handler = getattr(self, function_name)
219
return handler(str1, str2, int1, int2)
220
except AttributeError:
223
def gtk_widget_show(self, widget, *args):
226
The widget is showed.
227
Equivalent to widget.show()
231
def gtk_widget_hide(self, widget, *args):
234
The widget is hidden.
235
Equivalent to widget.hide()
239
def gtk_widget_grab_focus(self, widget, *args):
242
The widget grabs the focus.
243
Equivalent to widget.grab_focus()
247
def gtk_widget_destroy(self, widget, *args):
250
The widget is destroyed.
251
Equivalent to widget.destroy()
255
def gtk_window_activate_default(self, window, *args):
258
The default widget of the window is activated.
259
Equivalent to window.activate_default()
261
widget.activate_default()
263
def gtk_true(self, *args):
266
Equivalent to return True in a callback.
267
Useful for stopping propagation of signals.
271
def gtk_false(self, *args):
274
Equivalent to return False in a callback.
278
def gtk_main_quit(self, *args):
281
Equivalent to self.quit()
287
Starts the main loop of processing events.
288
The default implementation calls gtk.main()
290
Useful for applications that needs a non gtk main loop.
291
For example, applications based on gstreamer needs to override
292
this method with gst.main()
294
Do not directly call this method in your programs.
295
Use the method run() instead.
301
Quit processing events.
302
The default implementation calls gtk.main_quit()
304
Useful for applications that needs a non gtk main loop.
305
For example, applications based on gstreamer needs to override
306
this method with gst.main_quit()
312
Starts the main loop of processing events checking for Control-C.
314
The default implementation checks wheter a Control-C is pressed,
315
then calls on_keyboard_interrupt().
317
Use this method for starting programs.
321
except KeyboardInterrupt:
322
self.on_keyboard_interrupt()
324
def on_keyboard_interrupt(self):
326
This method is called by the default implementation of run()
327
after a program is finished by pressing Control-C.
331
def install_custom_handler(self, custom_handler):
332
gtk.glade.set_custom_handler(custom_handler)
334
def create_glade(self, glade_path, root, domain):
335
return gtk.glade.XML(self.glade_path, root, domain)
337
def get_widget(self, widget_name):
338
return self.glade.get_widget(widget_name)
340
def get_widgets(self):
341
return self.glade.get_widget_prefix("")