mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <HTML><HEAD><TITLE>Using python to create Macintosh applications, part two</TITLE></HEAD>
 | |
| <BODY>
 | |
| <H1>Using python to create Macintosh applications, part two</H1>
 | |
| <HR>
 | |
| 
 | |
| In this document we rewrite the application of the <A
 | |
| HREF="example1.html">previous example</A> to use modeless dialogs. We
 | |
| will use an application framework, and we will have a look at creating
 | |
| applets, standalone applications written in Python.  The <A
 | |
| HREF="example2/dnslookup-2.py">source code</A> and 
 | |
| <A HREF="example2/dnslookup-2.rsrc">resource file</A> are available in the folder 
 | |
| <A HREF="example2">example2</A>. <p>
 | |
| 
 | |
| Again, we start with ResEdit to create our dialogs. Not only do we
 | |
| want a main dialog this time but also an "About" dialog.  This example is less
 | |
| than complete since we do not provide a <A NAME="bundle">BNDL resource</A> 
 | |
| and related stuff that an application cannot be without. We are able to do this
 | |
| when building a python applet since BuildApplet will substitute default resources
 | |
| for BNDL, etc. when none are supplied (<A HREF="#no-bundle">See below</A>.)
 | |
| "Inside Mac" or various
 | |
| books on Macintosh programming will help here. Also, you can refer to
 | |
| the resource files provided in the Python source distribution for some
 | |
| of the python-specific points of BNDL programming: the
 | |
| "appletbundle.rsrc" file is what is used for creating applets if you
 | |
| don't provide your own resource file. <p>
 | |
| 
 | |
| When creating your own BNDL resouorces, keep in mind that the Finder gets 
 | |
| confused if you have more than one application with the same signature. This may be due 
 | |
| to some incorrectness on the side of "BuildApplet", I am not sure.  There is one 
 | |
| case when you definitely need a unique signature: when you create an applet that 
 | |
| has its own data files and you want the user to be able to start your
 | |
| applet by double-clicking one of the datafiles. <p>
 | |
| 
 | |
| Let's have a look at dnslookup-2.rsrc, our resource file. Dialog 512 is the
 | |
| main window which has one button (Lookup), two labels and
 | |
| two text entry areas, one of which is used for output only. The "Quit"
 | |
| button has disappeared, because its function is handled by a menu choice.  Here's
 | |
| what it will look like at run time:<p>
 | |
| <div align=center>
 | |
| <img width=324 height=205 src="example2/dnslookup-2.gif" alt="dialog image">
 | |
| </div>
 | |
| <p>
 | |
| 
 | |
| <H2>A modeless dialog application using FrameWork</H2>
 | |
| 
 | |
| On to the source code in <A
 | |
| HREF="example2/dnslookup-2.py">dnslookup-2.py</A>.  The
 | |
| start is similar to our previous example program <A
 | |
| HREF="example1/dnslookup-1.py">dnslookup-1.py</A>, with
 | |
| one extra module being imported. To make life more simple we will use
 | |
| the <CODE>FrameWork</CODE> module, a nifty piece of code that handles
 | |
| all the gory Mac details of event loop programming, menubar
 | |
| installation and all the other code that is the same for every Mac
 | |
| program in the world.  Like most standard modules, FrameWork will run
 | |
| some sample test code when you invoke it as a main program, so try it
 | |
| now. It will create a menu bar with an Apple menu with the about box
 | |
| and a "File" menu with some pythonesque choices (which do nothing
 | |
| interesting, by the way) and a "Quit" command that works. <p>
 | |
| 
 | |
| <BLOCKQUOTE>
 | |
| If you have not used <code>FrameWork</code> before you may want to
 | |
| first take a look at the <A HREF="textedit.html">Pathetic EDitor</A>
 | |
| example, which builds a minimal text editor using FrameWork and TextEdit.
 | |
| On the other hand: we don't use many features of FrameWork, so you could
 | |
| also continue with this document. 
 | |
| </BLOCKQUOTE>
 | |
| 
 | |
| After the imports we get the definitions of resource-IDs in our
 | |
| resource file, slightly changed from the previous version of our
 | |
| program. The main program is also
 | |
| similar to our previous version, with one important exception: we
 | |
| first check to see whether our resource is available before opening
 | |
| the resource file. Why is this? Because later, when we will have
 | |
| converted the script to an applet, our resources will be available in
 | |
| the applet file and we don't need the separate resource file
 | |
| anymore. <p>
 | |
| 
 | |
| Next comes the definition of our main class,
 | |
| <CODE>DNSLookup</CODE>, which inherits
 | |
| <CODE>FrameWork.Application</CODE>. The Application class handles the
 | |
| menu bar and the main event loop and event dispatching. In the
 | |
| <CODE>__init__</CODE> routine we first let the base class initialize
 | |
| itself, then we create our modeless dialog and finally we jump into
 | |
| the main loop. The main loop continues until we call <CODE>self._quit</CODE>,
 | |
| which we will do when the user selects "Quit". When we create
 | |
| the instance of <CODE>MyDialog</CODE> (which inherits
 | |
| <CODE>DialogWindow</CODE>, which inherits <CODE>Window</CODE>) we pass
 | |
| a reference to the application object, this reference is used to tell
 | |
| Application about our new window.  This enables the event loop to keep
 | |
| track of all windows and dispatch things like update events and mouse
 | |
| clicks. <p>
 | |
| 
 | |
| The <CODE>makeusermenus()</CODE> method (which is called sometime
 | |
| during the Application <CODE>__init__</CODE> routine) creates a File
 | |
| menu with a Quit command (shortcut command-Q), which will callback to
 | |
| our quit() method. <CODE>Quit()</CODE>, in turn, calls <CODE>_quit</CODE> which
 | |
| causes the mainloop to terminate at a convenient time. <p>
 | |
| 
 | |
| Application provides a standard about box, but we override this by
 | |
| providing our own <CODE>do_about()</CODE> method which shows an about
 | |
| box from a resource as a modal dialog. This piece of code should look
 | |
| familiar to you from the previous example program. That do_about is
 | |
| called when the user selects About from the Apple menu is, again,
 | |
| taken care of by the __init__ routine of Application. <p>
 | |
| 
 | |
| The <CODE>MyDialog</CODE> class is the container for our main
 | |
| window. Initialization is again done by first calling the base class
 | |
| <CODE>__init__</CODE> function and finally setting the local variable
 | |
| "parent." <p>
 | |
| 
 | |
| <CODE>Do_itemhit()</CODE> is called when an item is selected in this
 | |
| dialog by the user. We are passed the item number (and the original
 | |
| event structure, which we normally ignore). The code is similar to the
 | |
| main loop of our previous example program: a switch depending on the
 | |
| item selected.  <CODE>Dnslookup()</CODE> is quite similar to our previous 
 | |
| example. <p>
 | |
| 
 | |
| <H2><IMG SRC="html.icons/mkapplet.gif"><A NAME="applets">Creating applets</A></H2>
 | |
| 
 | |
| Now let us try to turn the python script into an applet, a standalone
 | |
| application. This will <em>not</em> work if you have the "classic 68k"
 | |
| Python distribution, only if you have the cfm68k or PPC distribution.
 | |
| 
 | |
| <blockquote>
 | |
| Actually, "standalone" is probably not the correct term here, since an
 | |
| applet does still depend on a lot of the python environment: the
 | |
| PythonCore shared library, the Python Preferences file, the python Lib
 | |
| folder and any other modules that the main module depends on. It is
 | |
| possible to get rid of all these dependencies and create true standalone
 | |
| applications in Python, but this is a bit difficult. See <a href="freezing.html">
 | |
| Standalone Applications in Python</a> for details. For this
 | |
| document, by standalone we mean here that
 | |
| the script has the look-and-feel of an application, including the
 | |
| ability to have its own document types, be droppable, etc.
 | |
| </blockquote>
 | |
| 
 | |
| The easiest way to create an applet is to take your source file and
 | |
| drop it onto "BuildApplet", located in the Python home
 | |
| folder. This will create an applet with the same name as your python
 | |
| source with the ".py" stripped. Also, if a resource file with the same
 | |
| name as your source but with ".rsrc" extension is available the
 | |
| resources from that file will be copied to your applet too. If there
 | |
| is no resource file for your script a set of default resources will be
 | |
| used, and the applet will have the default creator 'Pyt0'. The latter
 | |
| also happens if you do have a resource file but without the BNDL
 | |
| combo. <A NAME="no-bundle">Actually</A>, as in the present example.
 | |
| <p>
 | |
| 
 | |
| If you need slightly more control over the BuildApplet process you can
 | |
| double-click it, and you will get dialogs for source and
 | |
| destination of the applet. The rest of the process, including locating
 | |
| the resource file, remains the same. <p>
 | |
| 
 | |
| Note that though our example application completely bypasses the
 | |
| normal python user interface this is by no means necessary. Any python
 | |
| script can be turned into an applet, and all the usual features of the
 | |
| interpreter still work. <p>
 | |
| 
 | |
| That's all for this example, you may now return to the <A HREF="index.html">
 | |
| table of contents</A> to pick another topic. <p>
 | |
| </BODY>
 | |
| </HTML>
 | 
