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 281 282 283 284 285 286 287 288 289
|
<!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="multipleproxies.html" />
<link rel="parent" href="node16.html" />
<link rel="next" href="node26.html" />
<meta name='aesop' content='information' />
<title>2.9.9 Other Proxy features</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.8 Multiple Proxies"
href="multipleproxies.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="3 Widgets"
href="node26.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="multipleproxies.html">2.9.8 Multiple Proxies</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="node26.html">3 Widgets</A>
</div>
<hr /></div>
</DIV>
<!--End of Navigation Panel-->
<div class='online-navigation'>
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></a>
<UL CLASS="ChildLinks">
<LI><A href="undo.html#SECTION000299100000000000000">2.9.9.1 Types</a>
<LI><A href="undo.html#SECTION000299200000000000000">2.9.9.2 Formats</a>
<LI><A href="undo.html#SECTION000299300000000000000">2.9.9.3 "Instant-apply" and Undo</a>
<LI><A href="undo.html#SECTION000299400000000000000">2.9.9.4 Proxy startup values</a>
</ul>
<!--End of Table of Child-Links-->
</div>
<HR>
<H3><A NAME="SECTION000299000000000000000">
2.9.9 Other Proxy features</A>
</H3>
<P>
Proxies are complex and featureful beasts; this section discusses some
additional details on them.
<P>
<H4><A NAME="SECTION000299100000000000000">
2.9.9.1 Types</A>
</H4>
<P>
GTK+ treats most of the information in the interface as strings - its
API usually takes data as strings, and it returns strings. However, this
is a bit of a problem when dealing with an associated model, since the
model may very well use integer, float or any other types internally.
<P>
For numeric types, Proxies have special support. On startup, the Proxy
will look at the attached model and try and detect what attributes are
numeric, by looking at their current values. Of course, if there is no
value in the model, or it is a string, it will be assumed to be a
string; however, if it is a number (float or integer) it will be
remembered, and the Proxy will convert it from the GTK's internal string
to a numeric type before sending it to the model. Note that this
conversion is rather dumb and if invalid characters are used, exceptions
will be raised (that's about it, though; the mainloop allows the
application to go on running); use a validated Entry<A NAME="tex2html10"
HREF="#foot427"><SUP>10</SUP></A> to avoid this problem.
<P>
For other types, you must convert from strings using getter and setter
methods. If dealing with numeric types, you can also manually convert in
the <code>set_*()</code> method and avoid any risks.
<P>
<H4><A NAME="SECTION000299200000000000000"></A>
<A NAME="formats"></A>
<BR>
2.9.9.2 Formats
</H4>
<P>
To avoid needing to provide accessors to deal with simple format
conversions, Proxies provide a way to set Python format strings that
will be applied to the attribute value when it is being applied to the
widget. The syntax is: <code>proxy.set_format(<I>attribute name</I>,
<I>format string</I>)</code> - the name is a string with the name of the
attribute. You can pass a list of strings, optionally, to apply the same
format string to multiple attributes.
<P>
Note that this does <I>not</I> apply to the data that is set <I>to</I> the
model from the interface; it will be send without any conversion. Think
of it as a simple, one-way filter for data sent from the model to the
interface.
<P>
<H4><A NAME="SECTION000299300000000000000"></A>
<A NAME="undo"></A>
<BR>
2.9.9.3 "Instant-apply" and Undo
</H4>
<P>
The proxy can present something of a hazard for complex applications if
its "instant-apply" model is not understood completely. Instant-apply
means that, at any time, the UI and the model have the same state. If
you pop up a dialog with a Proxy, and you alter the model, even before
clicking "OK" the value in the model will have changed.
<P>
This may cause two classes of problems. The first is undoing the changes
performed upon the model during manipulation of the Proxy (think "cancel
button" if you are having a hard time imagining why). Solutions:
<P>
<UL>
<LI>One solution would be to store the initial state of the instance -
<tt class="module">pickle</tt> can probably be used for implementing this. If Undo is
necessary, just reset the state of the model to the saved state. I have
not yet tested this, but I think it would work.
<P>
</LI>
<LI>If you are using Zope.com's <I>excellent</I> database
<em class="citetitle"><a
href="http://www.amk.ca/zodb/"
title="ZODB"
>ZODB</a></em>, you already have undo and
rollback mechanisms in your persistent objects, and all you need to do
is call the appropriate method and your model state is back to the
previous state.
<P>
</LI>
<LI>Kiwi may at some point offer undo functionality, which would allow
one to undo selectively changes done to the model in the Proxy. At the
moment, this is just an idea, but I imagine it would not be hard to
implement.
</LI>
</UL>
<P>
The second problem is using the model in another part of the application
simultaneously (think "I am editing a price at the same time she is
selling the product"). This problem can be aggravated when using
multiple proxies attached to the same model. Solutions:
<P>
<UL>
<LI>You can offer a copy of your instance as the actual proxy
instance, and upon finishing editing using the proxy (or upon
"committing" the changes) you can transfer the state from the copy to
the real instance. This way, the application continues using the real
instance normally, and the proxy uses the copy without risking hard to
the application itself.
<P>
</LI>
<LI>The Proxy could implement this solution internally, too; an idea
would be a sort of GhostProxy, which had a <code>commit()</code> method which
copied state automatically from the "ghost" to the real model.
</LI>
</UL>
<P>
(Yes, this part needs more research. I'll be looking into it.)
<P>
<H4><A NAME="SECTION000299400000000000000">
2.9.9.4 Proxy startup values</A>
</H4>
<P>
When starting up a Proxy, the model attributes to be attached to the
Proxy are analyzed and the initial state of the Proxy interface is set.
The process by which this is performed is rather involved, and for the
sake of completeness (debugging these things can be a bit tiresome), is
listed here:
<P>
<UL>
<LI>If the model's attribute value is <B>unset</B>, and there is no
accessor, the default value in the interface (specified in Glade or GTK
previously to initializing the Proxy) is used <I>and is set to the
model attribute</I>.
</LI>
<LI>If the instance variable is set but is <code>None</code>, the following
defaults are used for each widget:
<UL>
<LI><B>gtk.Entry, gtk.Label, gtk.Combo, gtk.Text, gtk.SpinButton</B>: an
empty string is set to the model, and a blank widget is presented.
</LI>
<LI><B>gtk.RadioButton</B>: The button set in Glade or GTK as
initially on is selected, and if none is selected, the button that
is most to the top and left of the Proxy interface is selected. The
value associated with the radiobutton is set to the model attribute.
</LI>
<LI><B>gtk.OptionMenu</B>: the first item in the menu is selected, and
its value is set to the model attribute.
</LI>
<LI><B>gtk.ToggleButton and gtk.CheckButton</B>: the widgets are set
to unselected, and the model attribute is set to 0 (zero).
</LI>
</UL>
</LI>
</UL>
<P>
<BR><HR><H4>Footnotes</H4>
<DL>
<DT><A NAME="foot427">... Entry</A><A
href="undo.html#tex2html10"><SUP>10</SUP></A></DT>
<DD>To be
released in the next version of Kiwi, but some examples have been posted
to pygtk-list
</DD>
</DL>
<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.8 Multiple Proxies"
href="multipleproxies.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="3 Widgets"
href="node26.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="multipleproxies.html">2.9.8 Multiple Proxies</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="node26.html">3 Widgets</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>
|