In this tutorial we will write a custom widget which offers typing suggestions when entering usernames.
If you find yourself needing to write a custom widget, please contact the Rose team for guidance.
Create a new Rose app by running the following command replacing
DIRECTORY with the path in which to create the suite:
rose tutorial widget <DIRECTORY> cd <DIRECTORY>
You will now have a Rose app which contains the following files:
<DIRECTORY>/ |-- meta/ | `-- lib/ | `-- python/ | `-- widget/ | |-- __init__.py | `-- username.py `-- rose-app.conf
rose-app.conf file defines an environment variable called
__init__.py file is empty - the presence of this file declares the
widget directory as a python package.
username.py file is where we will write our widget.
We will start with a slimmed-down copy of the class
rose.config_editor.valuewidget.text.RawValueWidget which you will
find in the file
username.py. It contains all the API calls you would
normally ever need.
We are now going to extend the widget to be more useful.
Add a line importing the
pwd package at the top of the file:
+ import pwd import gobject import pygtk pygtk.require('2.0') import gtk
This adds the Python library that we’ll use in a minute.
Now we need to create a predictive text model by adding some data to our
gtk.Entry text widget.
We need to write our method
_set_completion, and put it in the main body
of the class. This will retrieve usernames from the
function and store them so they can be used by the text widget
Add the following method to the
def _set_completion(self): # Return a predictive text model. completion = gtk.EntryCompletion() model = gtk.ListStore(str) for username in [p.pw_name for p in pwd.getpwall()]: model.append([username]) completion.set_model(model) completion.set_text_column(0) completion.set_inline_completion(True) self.entry.set_completion(completion)
We need to make sure this method gets called at the right time, so we add
the following line to the
self.entry.show() + gobject.idle_add(self._set_completion) self.pack_start(self.entry, expand=True, fill=True, padding=0)
We could just call
self._set_completion() there, but this would hang the
config editor while the database is retrieved.
Instead, we’ve told GTK to fetch the predictive text model when it’s next idle
gobject.idle_add). This means it will be run after it finishes loading
the page, and will be more-or-less invisible to the user. This is a better
way to launch something that may take a second or two. If it took any longer,
we’d probably want to use a separate process.
Referencing the Widget¶
Now we need to refer to it in the metadata to make use of it.
Create the file
meta/rose-meta.conf and paste the following configuration
This means that we’ve set our widget up for the option
under the section env. It will now be used as the widget for this