blob: 2c3cd2272f229d1b0915bee8b172ee52273b38a5 [file] [log] [blame]
Jack Jansena6308131996-03-18 13:38:52 +00001<HTML><HEAD><TITLE>Using python to create Macintosh applications, part two</TITLE></HEAD>
2<BODY>
3<H1>Using python to create Macintosh applications, part two</H1>
4<HR>
5
6In this document we rewrite the application of the <A
7HREF="example1.html">previous example</A> to use modeless dialogs. We
8will use an application framework, and we will have a look at creating
Jack Jansen2450a251999-12-03 15:15:28 +00009applets, standalone applications written in Python. The <A
10HREF="example2/dnslookup-2.py">source code</A> and
11<A HREF="example2/dnslookup-2.rsrc">resource file</A> are available in the folder
12<A HREF="example2">example2</A>. <p>
Jack Jansena6308131996-03-18 13:38:52 +000013
14Again, we start with ResEdit to create our dialogs. Not only do we
Jack Jansen2450a251999-12-03 15:15:28 +000015want a main dialog this time but also an "About" dialog. This example is less
16than complete since we do not provide a <A NAME="bundle">BNDL resource</A>
17and related stuff that an application cannot be without. We are able to do this
18when building a python applet since BuildApplet will substitute default resources
19for BNDL, etc. when none are supplied (<A HREF="#no-bundle">See below</A>.)
20"Inside Mac" or various
21books on Macintosh programming will help here. Also, you can refer to
Jack Jansena6308131996-03-18 13:38:52 +000022the resource files provided in the Python source distribution for some
23of the python-specific points of BNDL programming: the
24"appletbundle.rsrc" file is what is used for creating applets if you
25don't provide your own resource file. <p>
26
Jack Jansen2450a251999-12-03 15:15:28 +000027When creating your own BNDL resouorces, keep in mind that the Finder gets
28confused if you have more than one application with the same signature. This may be due
29to some incorrectness on the side of "BuildApplet", I am not sure. There is one
30case when you definitely need a unique signature: when you create an applet that
31has its own data files and you want the user to be able to start your
Jack Jansena6308131996-03-18 13:38:52 +000032applet by double-clicking one of the datafiles. <p>
33
Jack Jansen2450a251999-12-03 15:15:28 +000034Let's have a look at dnslookup-2.rsrc, our resource file. Dialog 512 is the
35main window which has one button (Lookup), two labels and
Jack Jansendd206891999-12-03 16:00:20 +000036two text entry areas, one of which is used for output only. The "Quit"
Jack Jansen2450a251999-12-03 15:15:28 +000037button has disappeared, because its function is handled by a menu choice. Here's
38what it will look like at run time:<p>
39<div align=center>
40<img width=324 height=205 src="example2/dnslookup-2.gif" alt="dialog image">
41</div>
42<p>
Jack Jansena6308131996-03-18 13:38:52 +000043
44<H2>A modeless dialog application using FrameWork</H2>
45
46On to the source code in <A
Jack Jansen2450a251999-12-03 15:15:28 +000047HREF="example2/dnslookup-2.py">dnslookup-2.py</A>. The
Jack Jansena6308131996-03-18 13:38:52 +000048start is similar to our previous example program <A
Jack Jansen2450a251999-12-03 15:15:28 +000049HREF="example1/dnslookup-1.py">dnslookup-1.py</A>, with
Jack Jansena6308131996-03-18 13:38:52 +000050one extra module being imported. To make life more simple we will use
51the <CODE>FrameWork</CODE> module, a nifty piece of code that handles
Jack Jansen2450a251999-12-03 15:15:28 +000052all the gory Mac details of event loop programming, menubar
53installation and all the other code that is the same for every Mac
Jack Jansena6308131996-03-18 13:38:52 +000054program in the world. Like most standard modules, FrameWork will run
55some sample test code when you invoke it as a main program, so try it
56now. It will create a menu bar with an Apple menu with the about box
57and a "File" menu with some pythonesque choices (which do nothing
58interesting, by the way) and a "Quit" command that works. <p>
59
Jack Jansen08365421996-04-19 15:56:08 +000060<BLOCKQUOTE>
61If you have not used <code>FrameWork</code> before you may want to
62first take a look at the <A HREF="textedit.html">Pathetic EDitor</A>
63example, which builds a minimal text editor using FrameWork and TextEdit.
64On the other hand: we don't use many features of FrameWork, so you could
65also continue with this document.
66</BLOCKQUOTE>
Jack Jansena6308131996-03-18 13:38:52 +000067
68After the imports we get the definitions of resource-IDs in our
69resource file, slightly changed from the previous version of our
Jack Jansen2450a251999-12-03 15:15:28 +000070program. The main program is also
Jack Jansena6308131996-03-18 13:38:52 +000071similar to our previous version, with one important exception: we
72first check to see whether our resource is available before opening
73the resource file. Why is this? Because later, when we will have
74converted the script to an applet, our resources will be available in
75the applet file and we don't need the separate resource file
76anymore. <p>
77
78Next comes the definition of our main class,
Jack Jansen2450a251999-12-03 15:15:28 +000079<CODE>DNSLookup</CODE>, which inherits
Jack Jansena6308131996-03-18 13:38:52 +000080<CODE>FrameWork.Application</CODE>. The Application class handles the
81menu bar and the main event loop and event dispatching. In the
82<CODE>__init__</CODE> routine we first let the base class initialize
83itself, then we create our modeless dialog and finally we jump into
Jack Jansenef5cd051996-09-17 12:39:12 +000084the main loop. The main loop continues until we call <CODE>self._quit</CODE>,
Jack Jansen2450a251999-12-03 15:15:28 +000085which we will do when the user selects "Quit". When we create
Jack Jansena6308131996-03-18 13:38:52 +000086the instance of <CODE>MyDialog</CODE> (which inherits
87<CODE>DialogWindow</CODE>, which inherits <CODE>Window</CODE>) we pass
88a reference to the application object, this reference is used to tell
89Application about our new window. This enables the event loop to keep
90track of all windows and dispatch things like update events and mouse
91clicks. <p>
92
93The <CODE>makeusermenus()</CODE> method (which is called sometime
94during the Application <CODE>__init__</CODE> routine) creates a File
95menu with a Quit command (shortcut command-Q), which will callback to
Jack Jansenef5cd051996-09-17 12:39:12 +000096our quit() method. <CODE>Quit()</CODE>, in turn, calls <CODE>_quit</CODE> which
97causes the mainloop to terminate at a convenient time. <p>
Jack Jansena6308131996-03-18 13:38:52 +000098
99Application provides a standard about box, but we override this by
100providing our own <CODE>do_about()</CODE> method which shows an about
101box from a resource as a modal dialog. This piece of code should look
102familiar to you from the previous example program. That do_about is
103called when the user selects About from the Apple menu is, again,
104taken care of by the __init__ routine of Application. <p>
105
Jack Jansena6308131996-03-18 13:38:52 +0000106The <CODE>MyDialog</CODE> class is the container for our main
107window. Initialization is again done by first calling the base class
Jack Jansen2450a251999-12-03 15:15:28 +0000108<CODE>__init__</CODE> function and finally setting the local variable
109"parent." <p>
Jack Jansena6308131996-03-18 13:38:52 +0000110
111<CODE>Do_itemhit()</CODE> is called when an item is selected in this
112dialog by the user. We are passed the item number (and the original
113event structure, which we normally ignore). The code is similar to the
114main loop of our previous example program: a switch depending on the
Jack Jansen2450a251999-12-03 15:15:28 +0000115item selected. <CODE>Dnslookup()</CODE> is quite similar to our previous
116example. <p>
Jack Jansena6308131996-03-18 13:38:52 +0000117
118<H2><IMG SRC="html.icons/mkapplet.gif"><A NAME="applets">Creating applets</A></H2>
119
Jack Jansen3412c5d1997-08-27 14:08:22 +0000120Now let us try to turn the python script into an applet, a standalone
121application. This will <em>not</em> work if you have the "classic 68k"
Jack Jansena2139fe1998-02-25 15:40:35 +0000122Python distribution, only if you have the cfm68k or PPC distribution.
123
124<blockquote>
Jack Jansen3412c5d1997-08-27 14:08:22 +0000125Actually, "standalone" is probably not the correct term here, since an
126applet does still depend on a lot of the python environment: the
127PythonCore shared library, the Python Preferences file, the python Lib
128folder and any other modules that the main module depends on. It is
Jack Jansena2139fe1998-02-25 15:40:35 +0000129possible to get rid of all these dependencies and create true standalone
Jack Jansendd206891999-12-03 16:00:20 +0000130applications in Python, but this is a bit difficult. See <a href="freezing.html">
Jack Jansena2139fe1998-02-25 15:40:35 +0000131Standalone Applications in Python</a> for details. For this
132document, by standalone we mean here that
Jack Jansen3412c5d1997-08-27 14:08:22 +0000133the script has the look-and-feel of an application, including the
Jack Jansena2139fe1998-02-25 15:40:35 +0000134ability to have its own document types, be droppable, etc.
135</blockquote>
Jack Jansena6308131996-03-18 13:38:52 +0000136
137The easiest way to create an applet is to take your source file and
Jack Jansen3412c5d1997-08-27 14:08:22 +0000138drop it onto "BuildApplet", located in the Python home
139folder. This will create an applet with the same name as your python
Jack Jansena6308131996-03-18 13:38:52 +0000140source with the ".py" stripped. Also, if a resource file with the same
141name as your source but with ".rsrc" extension is available the
142resources from that file will be copied to your applet too. If there
143is no resource file for your script a set of default resources will be
Jack Jansen3412c5d1997-08-27 14:08:22 +0000144used, and the applet will have the default creator 'Pyt0'. The latter
Jack Jansena6308131996-03-18 13:38:52 +0000145also happens if you do have a resource file but without the BNDL
Jack Jansen2450a251999-12-03 15:15:28 +0000146combo. <A NAME="no-bundle">Actually</A>, as in the present example.
147<p>
Jack Jansena6308131996-03-18 13:38:52 +0000148
Jack Jansen3412c5d1997-08-27 14:08:22 +0000149If you need slightly more control over the BuildApplet process you can
150double-click it, and you will get dialogs for source and
Jack Jansena6308131996-03-18 13:38:52 +0000151destination of the applet. The rest of the process, including locating
152the resource file, remains the same. <p>
153
154Note that though our example application completely bypasses the
155normal python user interface this is by no means necessary. Any python
156script can be turned into an applet, and all the usual features of the
157interpreter still work. <p>
158
159That's all for this example, you may now return to the <A HREF="index.html">
160table of contents</A> to pick another topic. <p>
Jack Jansen2450a251999-12-03 15:15:28 +0000161</BODY>
162</HTML>