~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Mac/Demo/example1.html

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<HTML><HEAD><TITLE>Using python to create Macintosh applications, part one</TITLE></HEAD>
 
2
<BODY>
 
3
 
 
4
<H1>Using python to create Macintosh applications, part one</H1>
 
5
<HR>
 
6
 
 
7
This document will show you how to create a simple mac-style
 
8
application using Python. We will glance at how to use dialogs and
 
9
resources. <p>
 
10
 
 
11
The example application we look at will be a simple program with a
 
12
dialog that allows you to perform domain name lookups on IP addresses
 
13
and hostnames.
 
14
The <A HREF="example1/dnslookup-1.py">source code</A> and 
 
15
<A HREF="example1/dnslookup-1.rsrc">resource file</A> 
 
16
for this application are available in the <A
 
17
HREF="example1">example1</A> folder (which you will have to download
 
18
if you are reading this document over the net and if you want to look
 
19
at the resources). <p>
 
20
 
 
21
We will use the builtin module "socket" that allows a
 
22
Python program to perform all sorts of networking functions, and we 
 
23
will create the user interface around that. You should be able to run
 
24
the sample code with the standard Python distribution.<p>
 
25
 
 
26
<CITE>
 
27
If you are interested in building your own extensions to python you
 
28
should check out the companion document <A
 
29
HREF="plugins.html">Creating Macintosh Python C extensions</A>,
 
30
which tells you how to build your own C extension.
 
31
<p>
 
32
</CITE>
 
33
 
 
34
<H2><A NAME="dialog-resources">Creating dialog resources</A></H2>
 
35
 
 
36
Let us start with the creative bit: building the dialogs and creating
 
37
an icon for our program. For this you need ResEdit, and a reasonable
 
38
working knowledge of how to use it. "Inside Mac" or various books on
 
39
macintosh programming will help here. <p>
 
40
 
 
41
There is one fine point that deserves to be mentioned here: <A
 
42
NAME="resource-numbering">resource numbering</A>.  Because often your
 
43
resources will be combined with those that the Python interpreter and
 
44
various standard modules need you should give your DLOG and DITL
 
45
resources numbers above 512. 128 and below are reserved for Apple,
 
46
128-228 are for extensions like Tk,
 
47
228-255 for the Python interpreter and 256-511 for standard
 
48
modules. If you are writing a module that you will be distributing for
 
49
inclusion in other people's programs you may want to register a number
 
50
in the 256-511 range, contact Guido or myself or whoever you think is
 
51
"in charge" of Python for the Macintosh at the moment. Even though the
 
52
application we are writing at the moment will keep its resources in a
 
53
separate resource file it is still a good idea to make sure that no
 
54
conflicts arise: once you have opened your resource file any attempt
 
55
by the interpreter to open a dialog will also search your resource
 
56
file. <p>
 
57
 
 
58
Okay, let's have a look at dnslookup-1.rsrc, our resource file.
 
59
The DLOG and accompanying DITL resource both have number 512. Since
 
60
ResEdit creates both with default ID=128 you should take care to
 
61
change the number on both. The dialog itself is pretty basic: two
 
62
buttons (Lookup and Quit), two labels and
 
63
two text entry areas, one of which is used for output only.  Here's what
 
64
the dialog will look like at run time<p>
 
65
<div align=center>
 
66
<img width=324 height=189 src="example1/dnslookup-1.gif" alt="dialog image">
 
67
</div>
 
68
<p>
 
69
 
 
70
<H2><A NAME="modal-dialog">An application with a modal dialog</A></H2>
 
71
 
 
72
Next, we will have to write the actual application. For this example,
 
73
we will use a modal dialog. This means that we will put up the dialog
 
74
and go into a loop asking the dialog manager for events (buttons
 
75
pushed). We handle the actions requested by the user until the Quit
 
76
button is pressed, upon which we exit our loop (and the program). This
 
77
way of structuring your program is actually rather antisocial, since
 
78
you force the user to do whatever you, the application writer, happen
 
79
to want. A modal dialog leaves no way of escape whatsoever (except
 
80
command-option-escape), and is usually not a good way to structure
 
81
anything but the most simple questions.  Even then: how often have you
 
82
been confronted with a dialog asking a question that you could not
 
83
answer because the data you needed was obscured by the dialog itself?
 
84
In the next example we will look at an application that does pretty
 
85
much the same as this one but in a more user-friendly way. <p>
 
86
 
 
87
The code itself is contained in the file <A
 
88
HREF="example1/dnslookup-1.py"> dnslookup-1.py</A>. Have
 
89
a copy handy before you read on.  The file starts off with a
 
90
textstring giving a short description. Not many tools do anything with
 
91
this as yet, but at some point in the future we <EM>will</EM> have all
 
92
sorts of nifty class browser that will display this string, so just
 
93
include it. Just put a short description at the start of each module,
 
94
class, method and function.  After the initial description and some
 
95
comments, we import the modules we need. <p>
 
96
 
 
97
<A NAME="easydialogs"><CODE>EasyDialogs</CODE></A> is a handy standard
 
98
module that provides you with routines that put up common text-only
 
99
modal dialogs:
 
100
<UL>
 
101
<LI> <CODE>Message(str)</CODE>
 
102
displays the message "str" and an OK button,
 
103
<LI> <CODE>AskString(prompt, default)</CODE>
 
104
asks for a string, displays OK and Cancel buttons,
 
105
<LI> <CODE>AskYesNoCancel(question, default)</CODE>
 
106
displays a question and Yes, No and Cancel buttons.
 
107
</UL>
 
108
 
 
109
<A NAME="res"><CODE>Res</CODE></A> is a pretty complete interface to
 
110
the MacOS Resource Manager, described fully in Inside Mac. There is
 
111
currently no documentation of it, but the Apple documentation (or
 
112
Think Ref) will help you on your way if you remember two points:
 
113
<UL>
 
114
<LI> Resources are implemented as Python objects, and each routine
 
115
with a resource first argument is implemented as a python method.
 
116
<LI> When in doubt about the arguments examine the routines docstring,
 
117
as in <CODE>print Res.OpenResFile.__doc__</CODE>
 
118
</UL>
 
119
        
 
120
Similarly, <A NAME="dlg"><CODE>Dlg</CODE></A> is an interface to the
 
121
Dialog manager (with Dialogs being implemented as python objects and
 
122
routines with Dialog arguments being methods). The sys module you
 
123
know, I hope.  The string module is an often used module that enables
 
124
you to perform many string related operations.  In this case however, we
 
125
are only using the "digits" constant from the string module.  We could
 
126
have simply defined "digits" as "0123456789".  The socket module enables 
 
127
us to perform the domain name lookups. We
 
128
use two calls from it:
 
129
<UL>
 
130
<LI> <CODE>gethostbyaddr()</CODE>
 
131
returns the hostname associated with an IP address
 
132
<LI> <CODE>gethostbyname()</CODE>
 
133
returns the IP address associated with a hostname
 
134
</UL>
 
135
  
 
136
Next in the source file we get definitions for our dialog resource
 
137
number and for the item numbers in our dialog. These should match the
 
138
situation in our resource file dnslookup-1.rsrc,
 
139
obviously.<p>
 
140
 
 
141
On to the main program. We start off with opening our resource file,
 
142
which should live in the same folder as the python source. If we
 
143
cannot open it we use <CODE>EasyDialogs</CODE> to print a message and
 
144
exit. You can try it: just move the resource file somewhere else for a
 
145
moment. Then we call do_dialog() to do the real work. <p>
 
146
 
 
147
<CODE>Do_dialog()</CODE> uses <CODE>Dlg.GetNewDialog()</CODE> to open
 
148
a dialog window initialized from 'DLOG' resource ID_MAIN and putting
 
149
it on screen in the frontmost position.  Next, we go into a loop,
 
150
calling <CODE>Dlg.ModalDialog()</CODE> to wait for the next user
 
151
action. <CODE>ModalDialog()</CODE> will return us the item number that
 
152
the user has clicked on (or otherwise activated). It will handle a few
 
153
slightly more complicated things also, like the user typing into
 
154
simple textfields, but it will <EM>not</EM> do things like updating
 
155
the physical appearance of radio buttons, etc. See Inside Mac or
 
156
another programming guide for how to handle this
 
157
yourself. Fortunately, our simple application doesn't have to bother with this,
 
158
since buttons and textfields are the only active elements we have. So, we do a
 
159
simple switch on item number and call the appropriate routine to implement the
 
160
action requested. Upon the user pressing "Quit" we simply leave the loop and,
 
161
hence, <CODE>do_dialog()</CODE>. This will cause the python dialog object
 
162
<CODE>my_dlg</CODE> to be deleted and the on-screen dialog to disappear. <p>
 
163
 
 
164
<A NAME="dialog-warning">Time for a warning</A>: be very careful what
 
165
you do as long as a dialog is on-screen.  Printing something, for
 
166
instance, may suddenly cause the standard output window to appear over
 
167
the dialog, and since we took no measures to redraw the dialog it will
 
168
become very difficult to get out of the dialog. Also, command-period
 
169
may or may not work in this situation. I have also seen crashes in
 
170
such a situation, probably due to the multiple event loops involved or
 
171
some oversight in the interpreter. You have been warned. <p>
 
172
 
 
173
The implementation of the "Lookup" command can use a bit more
 
174
explaining: we get the necessary information with <CODE>dnslookup()</CODE>
 
175
but now we have to update the on-screen dialog to present this
 
176
information to the user. The <CODE>GetDialogItem()</CODE> method of
 
177
the dialog returns three bits of information about the given item: its
 
178
type, its data handle and its rect (the on-screen <CODE>x,y,w,h</CODE>
 
179
coordinates). We are only interested in the data handle here, on which
 
180
we call <CODE>SetDialogItemText()</CODE> to set our new text.  Note
 
181
here that python programmers need not bother with the C-string versus
 
182
pascal-string controversy: the python glue module knows what is needed
 
183
and converts the python string to the correct type. <p>
 
184
 
 
185
And that concludes our first example of the use of resources and
 
186
dialogs. Next, you could have a look at the source of EasyDialogs for
 
187
some examples of using input fields and filterprocs. Or, go on with
 
188
reading the <A HREF="example2.html">second part</A> of this document
 
189
to see how to implement a better version of this application.<p>
 
190
 
 
191
</BODY>
 
192
</HTML>
 
193