1
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6
7<html xmlns="http://www.w3.org/1999/xhtml">
8  <head>
9    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
10    
11    <title>Understanding existing PyObjC examples &mdash; PyObjC-Core 2.5.0b1 documentation</title>
12    
13    <link rel="stylesheet" href="/_static/default.css" type="text/css" />
14    <link rel="stylesheet" href="/_static/pygments.css" type="text/css" />
15    
16    <script type="text/javascript">
17      var DOCUMENTATION_OPTIONS = {
18        URL_ROOT:    '../',
19        VERSION:     '2.5.0b1',
20        COLLAPSE_INDEX: false,
21        FILE_SUFFIX: '.html',
22        HAS_SOURCE:  true
23      };
24    </script>
25    <script type="text/javascript" src="/_static/jquery.js"></script>
26    <script type="text/javascript" src="/_static/underscore.js"></script>
27    <script type="text/javascript" src="/_static/doctools.js"></script>
28    <link rel="top" title="PyObjC-Core 2.5.0b1 documentation" href="/index.html" />
29    <link rel="up" title="PyObjC Tutorials" href="index.html" />
30    <link rel="next" title="Creating your first PyObjC application." href="firstapp.html" />
31    <link rel="prev" title="PyObjC Tutorials" href="index.html" /> 
32  </head>
33  <body>
34    <div class="related">
35      <h3>Navigation</h3>
36      <ul>
37        <li class="right" style="margin-right: 10px">
38          <a href="/genindex.html" title="General Index"
39             accesskey="I">index</a></li>
40        <li class="right" >
41          <a href="/py-modindex.html" title="Python Module Index"
42             >modules</a> |</li>
43        <li class="right" >
44          <a href="firstapp.html" title="Creating your first PyObjC application."
45             accesskey="N">next</a> |</li>
46        <li class="right" >
47          <a href="index.html" title="PyObjC Tutorials"
48             accesskey="P">previous</a> |</li>
49        <li><a href="/index.html">PyObjC-Core 2.5.0b1 documentation</a> &raquo;</li>
50          <li><a href="index.html" accesskey="U">PyObjC Tutorials</a> &raquo;</li> 
51      </ul>
52    </div>  
53
54    <div class="document">
55      <div class="documentwrapper">
56        <div class="bodywrapper">
57          <div class="body">
58            
59  <div class="section" id="understanding-existing-pyobjc-examples">
60<h1>Understanding existing PyObjC examples<a class="headerlink" href="#understanding-existing-pyobjc-examples" title="Permalink to this headline">¶</a></h1>
61<div class="section" id="introduction">
62<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
63<p>This tutorial is aimed primarily at people with little or no background
64in Objective-C and Cocoa, and it will help you to understand PyObjC programs
65written by other people, such as the examples included with the distribution.
66This document is actually not a true tutorial: you do not get to build anything,
67only read and examine things.</p>
68<p>It is strongly suggested that you first do the
69<a class="reference internal" href="firstapp.html"><em>Creating your first PyObjC application</em></a> tutorial to get some hands-on
70experience with PyObjC, Cocoa and especially Interface Builder.</p>
71</div>
72<div class="section" id="model-view-controller">
73<h2>Model-View-Controller<a class="headerlink" href="#model-view-controller" title="Permalink to this headline">¶</a></h2>
74<p>If you have used another GUI toolkit in the past it is essential that
75you understand that Cocoa is different.  For this once this isn&#8217;t
76marketing-speak: Cocoa is inherently different from common toolkits such as
77Tk, wxWindows, Carbon, MFC, etc.  Apple&#8217;s documentation explains this, but
78such introductory text is often skipped.  It is a good idea to refer back to
79<a class="reference external" href="http://developer.apple.com/documentation/Cocoa/Conceptual/AppArchitecture/index.html">Application Architecture</a> after reading this section.  If you want, you can
80write code that does not follow the Model-View-Controller paradigm, but you
81would be on your own.  Cocoa and Interface Builder are designed to suit this
82model.</p>
83<p>Cocoa is built on the Model-View-Controller paradigm (MVC).  What this means
84is that the application code should be split into three parts:</p>
85<ul class="simple">
86<li>The <em>Model</em> is the storage of and operations on the data.  The model
87could be as complicated as a large database, or as simple as a
88currency conversion function that only knows how to multiply two floating
89point numbers, as in the Currency Converter application built in the first
90tutorial.</li>
91<li>The <em>View</em> is what the user sees and interacts with on-screen.</li>
92<li>The <em>Controller</em> is the glue that binds the Model and the View together.
93In the Currency Converter tutorial it is the callback that is triggered
94when the user presses the &#8220;Convert&#8221; button, which gets the data from the
95&#8220;amount&#8221; and &#8220;rate&#8221; fields of the View, passes them to the Model for
96computation and sends the result back to the View.</li>
97</ul>
98<p>To summarize: the Model knows nothing about the user, the View knows nothing
99about the data and operations, and the Controller only knows how to relate
100the Model and the View.  For really tiny applications, such as the currency
101converter, it may be tempting to do away with the Model and simply put that
102code in the Controller.  You probably shouldn&#8217;t do this, as it can make
103your code harder to read since it will be a mix of algorithms and glue code,
104however there is no technical limitation that prevents you from doing this.
105If you do combine the functionality of the model and controller, it is
106customary to name it as if it represented the document (without &#8220;Controller&#8221;).
107Note that the MVC paradigm is not specific to Cocoa and can be used with almost
108any GUI toolkit, but Cocoa is explicitly designed for this paradigm.</p>
109<p>You should have an MVC trio for every distinct unit of information in your
110program.  In case of a simple dialog-style application such as Currency
111Converter you will have one such trio.  Most applications, however, will have
112at least two: one for the application itself and one for the &#8220;documents&#8221; the
113application handles.  These may be real documents (i.e. files), but a document
114can be more abstract.  For example, if your application does scientific
115simulations that run in separate windows, each simulation could be a document.</p>
116</div>
117<div class="section" id="the-nib-file">
118<h2>The NIB file<a class="headerlink" href="#the-nib-file" title="Permalink to this headline">¶</a></h2>
119<p>Cocoa and Interface Builder strongly encourage you to use a NIB file
120per MVC trio.   You should follow this encouragement unless you are sure
121that you know what you are doing.</p>
122<p>This brings us to the second big difference between Cocoa and other GUI
123toolkits: almost all of the boilerplate code is replaced by the NIB.
124The source of Cocoa programs that do little work, especially example programs,
125will typically be much shorter than the equivalent with other toolkits.</p>
126<p>The NIB file is <em>not</em> a description of dialogs and menus and buttons, as you
127would get out of interface-builders for other toolkits.  A NIB file is more:
128it contains a archived object graph that represents the GUI, conceptually
129similar to a pickle in Python.  You tell Interface Builder
130about all the relevant classes in your application, the instances you
131want to create from those classes, and how the classes should connect to
132each other.  Interface Builder the actually instantiates the classes, makes
133all the connections and at that point freezes and stores the whole lot.</p>
134<p>Unarchival of a NIB happens in two phases.  The objects are restored using the
135<tt class="docutils literal"><span class="pre">NSCoding</span></tt> protocol (<tt class="docutils literal"><span class="pre">initWithCoder:</span></tt> is similar to <tt class="docutils literal"><span class="pre">__setstate__</span></tt> of
136Python&#8217;s <tt class="docutils literal"><span class="pre">pickle</span></tt> protocol), and then each object is sent an
137<tt class="docutils literal"><span class="pre">awakeFromNib:</span></tt> message so that they may do any initialization that depends
138on a fully restored object graph (<tt class="docutils literal"><span class="pre">pickle</span></tt> does not have this functionality
139built-in).</p>
140<p>The section above explains a lot of the strangeness in AppKit-based PyObjC
141applications:</p>
142<ul class="simple">
143<li>Windows and dialogs are typically not explicitly created, because they were
144instantiated by the NIB.</li>
145<li>Initialization is not always done in <tt class="docutils literal"><span class="pre">__init__</span></tt> or equivalent, because
146the object graph may not be completely unarchived until the first
147<tt class="docutils literal"><span class="pre">awakeFromNib:</span></tt> is called.</li>
148<li>Attributes that reference other objects are not typically set explicitly,
149but are done by the NIB file during unarchival.</li>
150</ul>
151<p>This also explains why you want separate NIB files for each MVC trio:
152the objects and classes in a NIB file are all unarchived together.  In other
153words, if you had created your document window in your application NIB
154(even if you set it to &#8220;hidden&#8221; initially so it does not show up) it would
155become very difficult to create a second window for a new document.</p>
156<p>If you think about the consequences of this section for a while it will
157become clear why all the boilerplate code is missing from Cocoa applications:
158you don&#8217;t need it.  Like the output of other gui-builders, a NIB usually
159contains enough information to recreate the view objects, but a NIB can also
160contain a large proportion of the setup for your Model and Controller
161functionality.  This is especially true when using <a class="reference external" href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/">Cocoa Bindings</a>.</p>
162</div>
163<div class="section" id="delegates">
164<h2>Delegates<a class="headerlink" href="#delegates" title="Permalink to this headline">¶</a></h2>
165<p>If you are familiar with other object-oriented GUI toolkits such as MFC
166another thing to notice is that Cocoa applications often use a <em>delegate</em>
167object where other toolkits would use a subclass.  For example: it is not
168common to use your own subclass of <tt class="docutils literal"><span class="pre">NSApplication</span></tt> for the main application
169object.  <tt class="docutils literal"><span class="pre">NSApplication</span></tt> objects have a helper called its <tt class="docutils literal"><span class="pre">delegate</span></tt>.
170The application object will attempt to inform its delegate many interesting
171events, and the delegate implements only the methods for the events it is
172interested in.</p>
173<p>For example, the method <tt class="docutils literal"><span class="pre">applicationShouldTerminate:</span></tt> of the delegate
174is called just before the application quits, and it has a chance to return
175<tt class="docutils literal"><span class="pre">NO</span></tt> if it is not appropriate to quit just yet.</p>
176</div>
177<div class="section" id="examining-a-nib-file">
178<h2>Examining a NIB file<a class="headerlink" href="#examining-a-nib-file" title="Permalink to this headline">¶</a></h2>
179<p>Let us examine the final NIB of the Currency Converter tutorial with this in
180mind.  If you open it and look at the main window (titled &#8220;MainMenu.nib&#8221;)
181and select the &#8220;Instances&#8221; pane you should see six objects.  Two of these
182have greyed-out names (&#8220;File&#8217;s Owner&#8221; and &#8220;First Responder&#8221;), these are present
183in every nib can not be changed.  The &#8220;File&#8217;s Owner&#8221; is either the Controller
184or the combined Model-Controller object, and is specified by the application
185when it loads the NIB.  For the main nib, which is loaded automatically by
186<tt class="docutils literal"><span class="pre">NSApplicationMain</span></tt> or <tt class="docutils literal"><span class="pre">PyObjCTools.AppHelper.runEventLoop</span></tt>, this will be
187the instance of <tt class="docutils literal"><span class="pre">NSApplication</span></tt>.  Currency Converter is not a document-based
188application, so the MVC trio for the conversion window are in here too.  These
189are named <tt class="docutils literal"><span class="pre">Converter</span></tt>, <tt class="docutils literal"><span class="pre">Window</span></tt> and <tt class="docutils literal"><span class="pre">ConverterController</span></tt> respectively.</p>
190<p>Let us have a look at the <tt class="docutils literal"><span class="pre">ConverterController</span></tt> object by double clicking it.
191The &#8220;MainMenu.nib&#8221; window goes to the &#8220;Classes&#8221; tab, and an info window shows
192up.  In the &#8220;MainMenu.nib&#8221; window the <tt class="docutils literal"><span class="pre">ConverterController</span></tt> class is
193selected, and you can see it is a subclass of <tt class="docutils literal"><span class="pre">NSObject</span></tt>.  Having the same
194name for the class and the instance is common in Cocoa programs, the main
195exception being the File Owner object.</p>
196<p>The info window shows more information on the <tt class="docutils literal"><span class="pre">ConverterController</span></tt> class.
197It should pop open to the &#8220;attributes&#8221; page.  In the &#8220;Outlets&#8221; tab you see that
198instances of this class have four attributes, <tt class="docutils literal"><span class="pre">converter</span></tt>, <tt class="docutils literal"><span class="pre">rateField</span></tt>,
199<tt class="docutils literal"><span class="pre">dollarField</span></tt> and <tt class="docutils literal"><span class="pre">totalField</span></tt>.  In any instance of <tt class="docutils literal"><span class="pre">ConverterController</span></tt>
200you can connect these to other objects, as we shall see below.  The &#8220;Actions&#8221;
201tab shows that there are two methods <tt class="docutils literal"><span class="pre">convert:</span></tt> and <tt class="docutils literal"><span class="pre">invertRate:</span></tt>, and
202again you can arrange for these to be called on instances of your
203<tt class="docutils literal"><span class="pre">ConverterController</span></tt> on certain events by making connections.</p>
204<p>So let us now look at the connections for our <tt class="docutils literal"><span class="pre">ConverterController</span></tt>
205<em>instance</em>.  Select the &#8220;Instances&#8221; tab in the main window, select
206<tt class="docutils literal"><span class="pre">ConverterController</span></tt> and set the info window to show &#8220;Connections&#8221;.  You
207now see all the outlets defined in the class.  Select one, and in the lower
208half of the info window you will see which object it connects to.  Moreover, a
209blue line will also link the object representations in the main window and
210in the dialog preview window.</p>
211<p>Finding out who calls your <tt class="docutils literal"><span class="pre">convert:</span></tt> method is more difficult, though, with
212this view.  But, if you select the &#8220;Convert&#8221; button in the dialog you will see
213that its <tt class="docutils literal"><span class="pre">target</span></tt> action will go to the <tt class="docutils literal"><span class="pre">ConverterController.convert_</span></tt>
214method.</p>
215<p>Luckily there is a way to find such incoming connections without reverting to
216guessing.  For instance, you will be hard put to find who, if anyone, calls
217<tt class="docutils literal"><span class="pre">ConverterController.invertRate_</span></tt>.  The solution: go to the &#8220;MainMenu.nib&#8221;
218window and look at the top of the vertical scrollbar.  There are two little
219icons there, one with lines and one with squares, with the squares being
220highlighted.  Press it.  The view will change to a scrollable list with objects
221in the left column and an indication of connections in the right column.  You
222can now see our ConverterController object has four outgoing connections (the
223ones we found earlier) and two incoming connections.  Click on the incoming
224connections icon.  The view will change again and ConverterController will
225probably scroll out of sight.  Locate it, and see that there are two lines
226going out of the ConverterController object.  One goes to <tt class="docutils literal"><span class="pre">NSButton(Convert)</span></tt>
227and is labeled <tt class="docutils literal"><span class="pre">convert:</span></tt>, we knew about that already.  The other one goes to
228an object <tt class="docutils literal"><span class="pre">NSMenuItem(Invert</span> <span class="pre">Exchange</span> <span class="pre">Rate)</span></tt> and is labeled <tt class="docutils literal"><span class="pre">invertRate:</span></tt>,
229so that is where calls to <tt class="docutils literal"><span class="pre">invertRate:</span></tt> come from.  And if you look at where
230this <tt class="docutils literal"><span class="pre">NSMenuItem</span></tt> sits in the object hierarchy you find that it is an entry
231in the &#8220;Edit&#8221; menu in the menubar.</p>
232</div>
233<div class="section" id="examining-an-apple-example">
234<h2>Examining an Apple example<a class="headerlink" href="#examining-an-apple-example" title="Permalink to this headline">¶</a></h2>
235<p>This section remains to be written.  Contributions will be gratefully accepted
236:-)</p>
237</div>
238</div>
239
240
241          </div>
242        </div>
243      </div>
244      <div class="sphinxsidebar">
245        <div class="sphinxsidebarwrapper">
246  <h3><a href="/index.html">Table Of Contents</a></h3>
247  <ul>
248<li><a class="reference internal" href="#">Understanding existing PyObjC examples</a><ul>
249<li><a class="reference internal" href="#introduction">Introduction</a></li>
250<li><a class="reference internal" href="#model-view-controller">Model-View-Controller</a></li>
251<li><a class="reference internal" href="#the-nib-file">The NIB file</a></li>
252<li><a class="reference internal" href="#delegates">Delegates</a></li>
253<li><a class="reference internal" href="#examining-a-nib-file">Examining a NIB file</a></li>
254<li><a class="reference internal" href="#examining-an-apple-example">Examining an Apple example</a></li>
255</ul>
256</li>
257</ul>
258
259  <h4>Previous topic</h4>
260  <p class="topless"><a href="index.html"
261                        title="previous chapter">PyObjC Tutorials</a></p>
262  <h4>Next topic</h4>
263  <p class="topless"><a href="firstapp.html"
264                        title="next chapter">Creating your first PyObjC application.</a></p>
265  <h3>This Page</h3>
266  <ul class="this-page-menu">
267    <li><a href="/_sources/tutorials/intro.txt"
268           rel="nofollow">Show Source</a></li>
269  </ul>
270<div id="searchbox" style="display: none">
271  <h3>Quick search</h3>
272    <form class="search" action="/search.html" method="get">
273      <input type="text" name="q" />
274      <input type="submit" value="Go" />
275      <input type="hidden" name="check_keywords" value="yes" />
276      <input type="hidden" name="area" value="default" />
277    </form>
278    <p class="searchtip" style="font-size: 90%">
279    Enter search terms or a module, class or function name.
280    </p>
281</div>
282<script type="text/javascript">$('#searchbox').show(0);</script>
283        </div>
284      </div>
285      <div class="clearer"></div>
286    </div>
287    <div class="related">
288      <h3>Navigation</h3>
289      <ul>
290        <li class="right" style="margin-right: 10px">
291          <a href="/genindex.html" title="General Index"
292             >index</a></li>
293        <li class="right" >
294          <a href="/py-modindex.html" title="Python Module Index"
295             >modules</a> |</li>
296        <li class="right" >
297          <a href="firstapp.html" title="Creating your first PyObjC application."
298             >next</a> |</li>
299        <li class="right" >
300          <a href="index.html" title="PyObjC Tutorials"
301             >previous</a> |</li>
302        <li><a href="/index.html">PyObjC-Core 2.5.0b1 documentation</a> &raquo;</li>
303          <li><a href="index.html" >PyObjC Tutorials</a> &raquo;</li> 
304      </ul>
305    </div>
306    <div class="footer">
307        &copy; Copyright 2009-2012, Ronald Oussoren.
308      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
309    </div>
310  </body>
311</html>