File: node27.html

package info (click to toggle)
kiwi 1.9.22-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, squeeze, wheezy
  • size: 11,912 kB
  • ctags: 5,549
  • sloc: python: 15,779; ansic: 193; xml: 77; makefile: 57; sh: 18
file content (280 lines) | stat: -rw-r--r-- 11,169 bytes parent folder | download | duplicates (3)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<link rel="STYLESHEET" href="howto.css" type='text/css' />
<link rel="first" href="howto.html" title='Developing applications with Kiwi' />
<link rel='last' href='about.html' title='About this document...' />
<link rel='help' href='about.html' title='About this document...' />
<link rel="prev" href="node26.html" />
<link rel="parent" href="node26.html" />
<link rel="next" href="node28.html" />
<meta name='aesop' content='information' />
<title>3.1 ObjectList</title>
</head>
<body>
<DIV CLASS="navigation">
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td class='online-navigation'><a rel="prev" title="3 Widgets"
  href="node26.html"><img src='previous.png'
  border='0' height='32'  alt='Previous Page' width='32' /></A></td>
<td class='online-navigation'><a rel="parent" title="3 Widgets"
  href="node26.html"><img src='up.png'
  border='0' height='32'  alt='Up One Level' width='32' /></A></td>
<td class='online-navigation'><a rel="next" title="4 References"
  href="node28.html"><img src='next.png'
  border='0' height='32'  alt='Next Page' width='32' /></A></td>
<td align="center" width="100%">Developing applications with Kiwi</td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
</tr></table>
<div class='online-navigation'>
<b class="navlabel">Previous:</b>
<a class="sectref" rel="prev" href="node26.html">3 Widgets</A>
<b class="navlabel">Up:</b>
<a class="sectref" rel="parent" href="node26.html">3 Widgets</A>
<b class="navlabel">Next:</b>
<a class="sectref" rel="next" href="node28.html">4 References</A>
</div>
<hr /></div>
</DIV>
<!--End of Navigation Panel-->

<H2><A NAME="SECTION000310000000000000000">
3.1 ObjectList</A>
</H2>

<P>
There is a special gtk.TreeView wrapper that accepts a list of columns,
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.

<P>
The ObjectList was designed for the very common task of presenting a
list of instance data in a gtk.TreeView. Elaborating an example: lets say we
have a set of <tt class="class">Person</tt> instances stored somewhere, each of these
instances possessing the attributes <code>name</code>, <code>address</code> and
<code>telephone</code>. A common problem is displaying a gtk.TreeView with this data
and performing an action when a person is selected. This is exactly the
use case which ObjectList supports.

<P>
Before showing an example, it's important to explain how the
ObjectList's constructor works, since it is rather special.

<P>
<div class="verbatim"><pre>
    class ObjectList:
        def __init__(self, columns, instance_list=None,
                     mode=gtk.SELECTION\_BROWSE)
</pre></div>

<P>
The ObjectList takes a <code>columns</code> parameter, and understanding it
is essential to using it correctly. <code>columns</code> should be a list of
<tt class="class">Column</tt> 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 <tt class="class">Column</tt>:

<P>
<div class="verbatim"><pre>
    class Column:
        __init__(self, attribute, title=None, data_type=True,
                 **kwargs)
</pre></div>

<P>
Each Column instance determines the properties of the ObjectList's column;
most important of these is <code>attribute</code>, which specifies the name of
the instance attribute the column should hold. Note that all of these
arguments but <code>attribute</code> are optional and can be safely be left
out. To create a ObjectList for our example above, with columns for "name",
"address" and "telephone", we could have something like:

<P>
<div class="verbatim"><pre>
    my_columns = [
        Column("name", sorted=True),
        Column("address"),
        Column("telephone", title="Phone")
    ]

    objects = ObjectList(my_columns)
</pre></div>

<P>
This section of code would create a new ObjectList with 3 columns,
being sorted by the first one, and using "Name", "Address" and "Phone"
as column titles. See the API reference for <tt class="class">ObjectList</tt> and
<tt class="class">Column</tt> to find out all the details on them; there are many
features, including sort ordering, tooltips, format strings and more.

<P>
Note that you can produce a complete <code>column</code> 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 <code>dump_columns()</code> on the delegate; this method creates
a list of <tt class="class">Column</tt> instances corresponding to the current state of
the ObjectList. This list can be reused in the ObjectList constructor,
making it easy to save and restore the ObjectList's state even between runs.

<P>
The <code>instance_list</code> 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 <B>must</B> offer either an accessor to the attribute specified
- the accessor name must be in the format <code>get_<I>attribute_name</I></code>() - or an attribute with the name specified (the
delegate will do a <code>getattr()</code> for it). Note that you can
instantiate a <tt class="class">ObjectList</tt> without a list and add it later by
calling <code>new_list(<I>instance_list</I>)</code>.

<P>
To exemplify the ObjectList, 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 ObjectList for
it (see <code>news/news2.py</code>):

<P>
<BR>
<PRE  CLASS="verbatim">#!/usr/bin/env python
import gtk

from kiwi.ui.objectlist import ObjectList, Column

class NewsItem:
    """An instance that holds information about a news article."""
    def __init__(self, title, author, url):
        self.title, self.author, self.url = title, author, url

# Assemble friendly Pigdog.org news into NewsItem instances so they can
# be used in the ObjectList
news = [
 NewsItem("Smallpox Vaccinations for EVERYONE", "JRoyale",
          "http://www.pigdog.org/auto/Power_Corrupts/link/2700.html"),
 NewsItem("Is that uranium in your pocket or are you just happy to see me?",
          "Baron Earl",
          "http://www.pigdog.org/auto/bad_people/link/2699.html"),
 NewsItem("Cut 'n Paste", "Baron Earl",
          "http://www.pigdog.org/auto/ArtFux/link/2690.html"),
 NewsItem("A Slippery Exit", "Reverend CyberSatan",
          "http://www.pigdog.org/auto/TheCorporateFuck/link/2683.html"),
 NewsItem("Those Crazy Dutch Have Resurrected Elvis", "Miss Conduct",
          "http://www.pigdog.org/auto/viva_la_musica/link/2678.html")
]

# Specify the columns: one for each attribute of NewsItem, the URL
# column invisible by default
my_columns = [Column("title", sorted=True),
              Column("author", justify=gtk.JUSTIFY_RIGHT),
              Column("url", title="URL", visible=False)]

objectlist = ObjectList(my_columns)
objectlist.add_list(news)

w = gtk.Window()
w.connect('delete-event', gtk.main_quit)
w.set_size_request(600, 250)

w.add(objectlist)

w.show_all()
gtk.main()
</PRE>
<P>
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 ObjectList.  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 <B>a SlaveView doesn't have a toplevel window associated to
it</B>. To be able to use the ObjectList, 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:

<P>
<DIV ALIGN="CENTER">
<IMG
  ALIGN="BOTTOM" BORDER="0"
 SRC="img10.png"
 ALT="\includegraphics[scale=0.88]{images/news2.eps}">

</DIV>

<P>
If you look at this image, you might notice some important details:

<OL>
<LI>There is a little arrow in the right corner of the Title column.
What is that? A sort indicator! The titles in the first column are
sorted ascending. The ObjectList is set up so that you can order it's columns
by clicking on the headers, and it even sorts numeric data properly. By
default the sorted column is the left-most one, but you can change that
by using the columns spec.

<P>
</LI>
<LI>There is a popup menu in the right corner of the image. What is
it? It's a list of the columns, allowing you to select which column is
displayed and which is hidden. As you can see, the URL column is hidden
(remember the False we passed in the <code>my_columns</code> list?) and
Title and Author are displayed.

<P>
Note that both features are built in to the Kiwi ObjectList, one of the
enhanced widgets we provide.
</LI>
<LI>(The gtk.TreeView has no window border around it. That's because I had to
do some magic to get this screenshot to display correctly. Don't worry
about it.)
</LI>
</OL>

<P>

<DIV CLASS="navigation">
<div class='online-navigation'>
<p></p><hr />
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td class='online-navigation'><a rel="prev" title="3 Widgets"
  href="node26.html"><img src='previous.png'
  border='0' height='32'  alt='Previous Page' width='32' /></A></td>
<td class='online-navigation'><a rel="parent" title="3 Widgets"
  href="node26.html"><img src='up.png'
  border='0' height='32'  alt='Up One Level' width='32' /></A></td>
<td class='online-navigation'><a rel="next" title="4 References"
  href="node28.html"><img src='next.png'
  border='0' height='32'  alt='Next Page' width='32' /></A></td>
<td align="center" width="100%">Developing applications with Kiwi</td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
</tr></table>
<div class='online-navigation'>
<b class="navlabel">Previous:</b>
<a class="sectref" rel="prev" href="node26.html">3 Widgets</A>
<b class="navlabel">Up:</b>
<a class="sectref" rel="parent" href="node26.html">3 Widgets</A>
<b class="navlabel">Next:</b>
<a class="sectref" rel="next" href="node28.html">4 References</A>
</div>
</div>
<hr />
<span class="release-info">Release 1.9.22, documentation updated on August, 2006.</span>
</DIV>
<!--End of Navigation Panel-->

</BODY>
</HTML>