1 """Support for loading glade files from your application directory.
3 The simplest interface will be templates.load() which will return a set
4 of widgets loaded from $APP_DIR/Templates.glade, e.g.
5 widgets=templates.load()
8 self.window=widgets.getWindow('main')
9 self.entry=widgets['text_entry']
10 widgets.autoConnect(self)
11 self.window.show_all()
13 If you wish to re-use a window then you should use the Templates class:
14 widgets=templates.Templates()
17 set=widgets.getWidgetSet('main')
18 # ... connect signal handlers
19 window=set.getWindow('main')
20 windows.append(window)
22 To use a template as part of a class, derive a class from ProxyWindow
24 class MyWindow(templates.ProxyWindow):
26 self.widgets=rox.templates.load(None, 'main_window', self)
27 templates.ProxyWindow.__init__(self, self.widgets['main_window'])
37 import gtk
.glade
as glade
39 def _get_templates_file_name(fname
):
41 fname
='Templates.glade'
42 if not os
.path
.isabs(fname
):
43 fname
=os
.path
.join(rox
.app_dir
, fname
)
47 """Class holding a loaded glade file."""
49 def __init__(self
, name
=None):
50 """Load the glade file. If name is an absolute path name then load
51 it, if a relative path name load that from the appdir or if None
52 the load $APP_DIR/Templates.glade."""
53 self
.fname
=_get_templates_file_name(name
)
55 # Ideally we should cache the file then generate the widgets
56 # using glade.xml_new_from_buffer(), but that is too buggy
57 #self.xml=file(self.fname, 'r').read()
61 def autoConnect(self
, dict_or_instance
):
62 """Specify what to use to connect the signals when an instance of the
63 widgets is created. dict_or_instance is either a dictionary where the
64 signal handlers are indexed by the name of the handler in the glade
65 file, or an instance of a class where the methods have the same
66 names as given in the glade file."""
68 self
.connect_to
=dict_or_instance
70 def connect(self
, handler_name
, func
):
71 """Manually specify the handler function for a signal. These are
72 not set until getWidgetSet is called."""
74 self
.signals
[handler_name
]=func
76 def getWidgetSet(self
, root
=''):
77 """Return a WidgetSet instance containing the widgets defined by
78 the glade file. If root is given it is the top level widget to return.
79 The signal handlers specified in connect() or autoConnect() are
80 connected at this point.
83 widgets
=WidgetSet(fname
=self
.fname
, root
=root
)
85 widgets
.autoConnect(self
.connect_to
)
86 for name
in self
.signals
:
87 widgets
.connect(name
, self
.signals
[name
])
91 """A set of widget instances created from a glade file."""
93 def __init__(self
, xml
=None, fname
=None, root
=''):
94 """A set of widget instances created from the glade file.
95 xml - the contents of the glade file.
96 fname - file name to load the glade file from
97 root - top level widget to create (and all is contained widgets), or
99 NOTE: one of xml or fname must be specified
105 self
.widgets
=glade
.XML(fname
, root
)
107 self
.widgets
=glade
.xml_new_from_buffer(xml
, len(xml
), root
)
109 def autoConnect(self
, dict_or_instance
):
110 """Specify what to use to connect the signals.
111 dict_or_instance is either a dictionary where the
112 signal handlers are indexed by the name of the handler in the glade
113 file, or an instance of a class where the methods have the same
114 names as given in the glade file."""
116 self
.widgets
.signal_autoconnect(dict_or_instance
)
118 def connect(self
, name
, func
):
119 """Manually specify the handler function for a signal."""
121 self
.widgets
.signal_connect(name
, func
)
123 def getWidget(self
, name
):
124 """Return the named widget."""
125 return self
.widgets
.get_widget(name
)
127 def getWindow(self
, name
):
128 """Return the named widget, which should be a gtk.Window. The
129 window is tracked by the window counting system, see
130 rox.toplevel_ref()."""
131 return ProxyWindow(self
.getWidget(name
))
133 def __getitem__(self
, key
):
134 """Return the named widget."""
136 widget
=self
.widgets
.get_widget(key
)
142 """This acts as a proxy for a GtkWindow or GtkDialog, except that
143 it calls the toplevel_(un)ref functions for you automatically.
144 It is designed to wrap a window loaded from a Glade template. You
145 can sub-class this to create your own classes."""
147 def __init__(self
, window
):
148 """Act as a proxy for window. Call toplevel_ref() and arrange
149 for toplevel_unref to be called on destruction."""
155 self
._window
.connect('destroy', rox
.toplevel_unref
)
157 def __getattr__(self
, name
):
158 """Get unrecognized attributes from the window we are proxying
161 win
=self
.__dict
__['_window']
163 raise AttributeError, '_window'
165 if hasattr(win
, name
):
166 return getattr(win
, name
)
167 raise AttributeError, name
169 def load(fname
=None, root
='', dict_or_instance
=None):
170 """Load the templates file and return the set of widgets.
171 fname - path to templates file: If it is an absolute path name then load
172 it, if a relative path name load that from the appdir or if None
173 the load $APP_DIR/Templates.glade.
174 root - name of top level widget (and all child widgets) to create
175 dict_or_instance - what to use to connect the signals.
176 It is either a dictionary where the
177 signal handlers are indexed by the name of the handler in the glade
178 file, or an instance of a class where the methods have the same
179 names as given in the glade file.
181 template
=Templates(fname
)
183 template
.autoConnect(dict_or_instance
)
184 return template
.getWidgetSet(root
)