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
|
<!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="next" href="multipleproxies.html" />
<link rel="prev" href="node22.html" />
<link rel="parent" href="node16.html" />
<link rel="next" href="multipleproxies.html" />
<meta name='aesop' content='information' />
<title>2.9.7 Models</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="2.9.6 Widget support in"
href="node22.html"><img src='previous.png'
border='0' height='32' alt='Previous Page' width='32' /></A></td>
<td class='online-navigation'><a rel="parent" title="2.9 Proxies and Models"
href="node16.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="2.9.8 Multiple Proxies"
href="multipleproxies.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="node22.html">2.9.6 Widget support in</A>
<b class="navlabel">Up:</b>
<a class="sectref" rel="parent" href="node16.html">2.9 Proxies and Models</A>
<b class="navlabel">Next:</b>
<a class="sectref" rel="next" href="multipleproxies.html">2.9.8 Multiple Proxies</A>
</div>
<hr /></div>
</DIV>
<!--End of Navigation Panel-->
<H3><A NAME="SECTION000297000000000000000">
2.9.7 Models</A>
</H3>
<P>
The <tt class="module">kiwi.model</tt> module <tt class="class">Model</tt> classes. As discussed
before, the <tt class="class">Model</tt> class provides a mechanism for updating the
user interface based on changed performed in the model instance.
<P>
This is a powerful mechanism that allows you to guarantee that the
interface is always up-to-date with relation to an instance; it should
be used with care, however, because the update semantics are not trivial
to understand - just imagine having custom callbacks that alter the
same attribute as the proxy callback and you will understand why it is
easy to get in recursive loops. This tip I can offer you, therefore:
avoid altering the model in custom callbacks, and only do it in special
situations.
<P>
You can also attach multiple proxies to the same model and have them
update automatically; the next section will discuss this further. Before
passing on to that, however, I need to describe a special <tt class="class">Model</tt>
called <tt class="class">PickledModel</tt>. To demonstrate by example, I will revisit
the first example we saw in this text, the Person editor from section
<A href="person.html#person">2</A>. Let's see the code again:
<P>
<BR>
<PRE CLASS="verbatim">#!/usr/bin/env python
import gtk
from kiwi.model import PickledModel
from kiwi.ui.delegates import ProxyDelegate
# define the class that holds our application data
class Person(PickledModel):
pass
person = Person.unpickle()
# create and run a proxy interface attached to person
view = ProxyDelegate(person, gladefile="Person",
widgets=["address", 'name', 'phone'],
delete_handler=gtk.main_quit)
view.focus_topmost()
view.show_and_loop()
# save changes done to the instance
person.save()
</PRE>
<P>
Looking at the code, you might notice three special issues:
<P>
<OL>
<LI>The class our model inherits from is <tt class="class">FrameWork.PickledModel</tt>.
</LI>
<LI>We actually get our model instance by making a call to
<code>Person.unpickle()</code>, passing the class <tt class="class">Person</tt> as
an argument.
</LI>
<LI>We call <code>person.save()</code> at the end of the program.
</LI>
</OL>
<P>
<tt class="class">PickledModel</tt> offers a very cheap way to offer persistence for
your model instances. If you are familiar with the ZODB, think of
<tt class="class">PickledModel</tt> as a cheapo implementation that allows you to save
and restore an instance. To use it:
<P>
<OL>
<LI>Have your model class inherit from PickledModel.
<P>
</LI>
<LI>Use the <code>PickledModel.unpickle</code> which is a class method on
your model. it takes a filename as the optional second parameter (if omitted,
it uses the name of the class, with an extension of ".pickle").
The method will try and load the model state from a pickle file,
and if it doesn't exist, will create a new model and return it to you.
If the pickle file is damaged, it will save it with the extension ".err"
(avoiding it being erased by an unwitting <code>save()</code> call).
<P>
</LI>
<LI>Use the <code>save()</code> method to save the pickle when you are
ready. You may specify a filename to it; otherwise, it uses the default
filename specified through the <code>set_filename()</code> method. Note that
<code>PickledModel.unpickle</code> makes the filename it tried to used the
default by calling <code>set_filename()</code> internally.
</LI>
</OL>
<P>
The <span class="file">diary3.py</span> example in <code>examples/diary/</code> uses pickling in a
more involved manner and is recommended as a reference.
<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="2.9.6 Widget support in"
href="node22.html"><img src='previous.png'
border='0' height='32' alt='Previous Page' width='32' /></A></td>
<td class='online-navigation'><a rel="parent" title="2.9 Proxies and Models"
href="node16.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="2.9.8 Multiple Proxies"
href="multipleproxies.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="node22.html">2.9.6 Widget support in</A>
<b class="navlabel">Up:</b>
<a class="sectref" rel="parent" href="node16.html">2.9 Proxies and Models</A>
<b class="navlabel">Next:</b>
<a class="sectref" rel="next" href="multipleproxies.html">2.9.8 Multiple Proxies</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>
|