summaryrefslogtreecommitdiff
path: root/trunk/dimbola/gtkapp.py
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/dimbola/gtkapp.py')
-rw-r--r--trunk/dimbola/gtkapp.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/trunk/dimbola/gtkapp.py b/trunk/dimbola/gtkapp.py
new file mode 100644
index 0000000..81a7d80
--- /dev/null
+++ b/trunk/dimbola/gtkapp.py
@@ -0,0 +1,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()))
+