There is a special type of SlaveDelegate that creates a columned list, each row of the list representing an instance. This is the first high-level class of the framework being described; high-level in the sense that it goes beyond simply organizing the UI and handler methods, offering functionality directed towards object-oriented development in Python.
The CListDelegate was designed for the very common task of presenting a
list of instance data in a GtkCList. Elaborating an example: lets say we
have a set of Person instances stored somewhere, each of these
instances possessing the attributes name
, address
and
telephone
. A common problem is displaying a GtkCList with this data
and performing an action when a person is selected. This is exactly the
use case which CListDelegate supports.
Before showing an example, it's important to explain how the CListDelegate's constructor works, since it is rather special.
class CListDelegate: def __init__(self, columns, instance_list=None, handler=None, mode=gtk.SELECTION_BROWSE)
The CListDelegate takes a columns
parameter, and understanding it
is essential to using it correctly. columns
should be a list of
Column instances, each of these instances representing a column
in the list (and therefore, an attribute in the instance). Let's have a
look at the constructor for Column:
class Column: __init__(self, attribute, title=None, visible=1, tooltip=None, justify=None, format=None, width=None, sorted=0, order=0)
Each Column instance determines the properties of the CList's column;
most important of these is attribute
, which specifies the name of
the instance attribute the column should hold. Note that all of these
arguments but attribute
are optional and can be safely be left
out. To create a CList for our example above, with columns for "name",
"address" and "telephone", we could have something like:
my_columns = [ Column("name", sorted=TRUE), Column("address"), Column("telephone", title="Phone") ] cd = ClistDelegate(my_columns)
This section of code would create a new CListDelegate with 3 columns, being sorted by the first one, and using "Name", "Address" and "Phone" as column titles. See the API reference for CListDelegate and Column to find out all the details on them; there are many features, including sort ordering, tooltips, format strings and more.
Note that you can produce a complete column
specification by
running the delegate once with a simple set of columns, manipulating
them in runtime (changing sort order and widths, hiding columns) and and
then calling dump_columns()
on the delegate; this method creates
a list of Column instances corresponding to the current state of
the CList. This list can be reused in the CListDelegate constructor,
making it easy to save and restore the CList's state even between runs.
The instance_list
parameter should provide a list of instances
to be inserted into the clist, and the handler is an optional callback
that will be run when items are selected in the clist. The instances in
the list must offer either an accessor to the attribute specified
- the accessor name must be in the format get_attribute_name
() - or an attribute with the name specified (the
delegate will do a getattr()
for it). Note that you can
instantiate a CListDelegate without a list and add it later by
calling new_list(instance_list)
.
To exemplify the CListDelegate, I'm going to build upon the News Browser
example we saw a while back. I'm going to need to change the news data
structures from tuples to instances, and create a CListDelegate for
it (see News/news2.py
):
Wow! Assuming you have data in the correct format, in some 25 lines you defined the data for your applications, and in about 5 lines you set up and created the CListDelegate. This example, though, doesn't do anything (try running it - it doesn't even flash a window open, which is what normally happens if you create a window but don't run the mainloop) because a SlaveView doesn't have a toplevel window associated to it. To be able to use the CListDelegate, we need to perform UI composition: attach it to a parent view. I'll show for now a screenshot of the generated widget inside a single window just so you know how it looks:
If you look at this image, you might notice some important details:
my_columns
list?) and
Title and Author are displayed.
Note that both features are built in to the Kiwi CList, one of the enhanced widgets we provide. You can use the CList independently of CListDelegate, of course; check the module documentation for more information.