1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
# Copyright (C) 2009 Lars Wirzenius <liw@liw.fi>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
'''Helper class for writing PyGTK applications.'''
import gobject
import gtk
class GtkApplication(object):
'''Base class for GTK+ applications.
This class provides some convenience functions for GTK+ applications.
It makes some assumptions to simplify things:
* The UI will be made with Glade and described with a .ui file,
using GtkBuilder.
* A dictionary of all widgets is created as the widgets attribute.
It is indexed by the name of the widget, as defined in the .ui file.
* Callbacks will be named on_widgetname_signalname. They will be connected
automatically if this naming convention is followed.
* Methods named widgetname_is_sensitive control the sensitivity of
widgets that need to become sensitive or not based on the state of
the program.
* signal callbacks and *_is_sensitive are methods of "controllers",
which are provided to setup_widgets as an argument, and which it
stores into the controllers attribute.
'''
def setup_widgets(self, glade_filename, controllers):
'''Find all widgets and connect them to signal handlers.
The list of controllers will be stored in the controllers
attribute.
'''
self.controllers = controllers
if not hasattr(self, 'widgets'):
self.widgets = {}
builder = gtk.Builder()
if builder.add_from_file(glade_filename) == 0:
raise Exception('GtkBuilder.add_from_file failed for %s' %
glade_filename)
for widget in builder.get_objects():
if isinstance(widget, gtk.Widget):
self.setup_a_widget(widget)
def setup_a_widget(self, widget):
name = widget.get_property('name')
self.widgets[name] = widget
for controller in self.controllers:
for attr in dir(controller):
prefix = 'on_%s_' % name
if attr.startswith(prefix):
signal_name = attr[len(prefix):]
method = getattr(controller, attr)
widget.connect(signal_name, method)
def set_sensitive(self):
'''Set all widgets to be sensitive or not.
The sensitivity of each widget is tested with a method called
widgetname_is_sensitive. The method must be in one of the controllers
given to setup_widgets.
You should call this whenever one of the conditions for sensitivity
changes.
'''
suffix = '_is_sensitive'
for controller in self.controllers:
for attrname in dir(controller):
if attrname.endswith(suffix):
widgetname = attrname[:-len(suffix)]
if widgetname in self.widgets:
widget = self.widgets[widgetname]
method = getattr(controller, attrname)
widget.set_sensitive(bool(method()))
|