/Mac/Demo/example2.html

http://unladen-swallow.googlecode.com/ · HTML · 162 lines · 142 code · 20 blank · 0 comment · 0 complexity · b79eefa7fb9464184c86e719739b9707 MD5 · raw file

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