Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- </head><body bgcolor="#ffffff" vlink="blue" link="blue"><div style="position:relative">
- <!-- AdFender script begin --><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=1&url=webcache.googleusercontent.com"><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=2&url=webcache.googleusercontent.com"><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=3&url=webcache.googleusercontent.com"><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=4&url=webcache.googleusercontent.com"><script type="text/javascript" src="http://local.adfender.com/adfender/elemhide.js"></script><!-- AdFender script end -->
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <meta name="Creator" content="LaTeX with hyperref package">
- <meta name="Producer" content="pdfTeX-1.40.3">
- <meta name="CreationDate" content="D:20080401083512+02'00'">
- <meta name="ModDate" content="D:20080401083512+02'00'">
- <meta name="Fullbanner" content="This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6">
- <title>Yet Another PyS60 Tutorial INCOMPLETE DRAFT VERSION Gunnar Misund</title>
- <table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="1"><b>Page 1</b></a></font></td></tr></tbody></table><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:524;left:319"><nobr>Yet Another PyS60 Tutorial</nobr></div>
- <div style="position:absolute;top:573;left:319"><nobr>INCOMPLETE DRAFT VERSION</nobr></div>
- <div style="position:absolute;top:907;left:319"><nobr>Gunnar Misund</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
- <div style="position:absolute;top:1012;left:319"><nobr>April 1, 2008</nobr></div>
- <div style="position:absolute;top:1039;left:319"><nobr>Østfold University College, Halden, Norway</nobr></div>
- </span></font>
- <div style="position:absolute;top:1437;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="2"><b>Page 2</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:1553;left:108"><nobr>2</nobr></div>
- </span></font>
- <div style="position:absolute;top:2699;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="3"><b>Page 3</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:3144;left:458"><nobr>Abstract</nobr></div>
- <div style="position:absolute;top:3183;left:184"><nobr>This PyS60 (Python for Symbian Series 60 mobile phones) tutorial is a byproduct of course in Mobile</nobr></div>
- <div style="position:absolute;top:3206;left:162"><nobr>Programming at Østfold University College, Halden, Norway, held in the Spring of 2008. It is meant as a</nobr></div>
- <div style="position:absolute;top:3229;left:162"><nobr>supplement to the array of ”traditional” sources for PyS60 documentation. We focus in particular on issues</nobr></div>
- <div style="position:absolute;top:3252;left:162"><nobr>that are either poorly documented, or poorly demonstrated, or both. We give numerous bare-bone examples</nobr></div>
- <div style="position:absolute;top:3276;left:162"><nobr>to make it easier for the eager programmer to develop the next mobile killer applications.</nobr></div>
- </span></font>
- <div style="position:absolute;top:3961;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="4"><b>Page 4</b></a></font></td></tr></tbody></table></div><font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:4264;left:108"><nobr>Table of Contents</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:4379;left:108"><nobr><a href="#4">Abstract</a></nobr></div>
- <div style="position:absolute;top:4379;left:749"><nobr>2</nobr></div>
- <div style="position:absolute;top:4418;left:108"><nobr><a href="#8">1 Under The Hood</a></nobr></div>
- <div style="position:absolute;top:4418;left:749"><nobr>2</nobr></div>
- <div style="position:absolute;top:4443;left:130"><nobr><a href="#8">1.1 3xHelloWorld . . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
- <div style="position:absolute;top:4443;left:749"><nobr>2</nobr></div>
- <div style="position:absolute;top:4467;left:130"><nobr><a href="#11">1.2 SystemInfo . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
- <div style="position:absolute;top:4467;left:749"><nobr>5</nobr></div>
- <div style="position:absolute;top:4491;left:130"><nobr><a href="#12">1.3 Filesystem . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
- <div style="position:absolute;top:4491;left:749"><nobr>6</nobr></div>
- <div style="position:absolute;top:4531;left:108"><nobr><a href="#15">2 Storing Stuff</a></nobr></div>
- <div style="position:absolute;top:4531;left:749"><nobr>9</nobr></div>
- <div style="position:absolute;top:4555;left:130"><nobr><a href="#15">2.1 Files .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
- <div style="position:absolute;top:4555;left:749"><nobr>9</nobr></div>
- <div style="position:absolute;top:4579;left:130"><nobr><a href="#15">2.2 Pickling,andhowtoeasilyextendPyS60 . . .</a> . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
- <div style="position:absolute;top:4579;left:749"><nobr>9</nobr></div>
- <div style="position:absolute;top:4603;left:130"><nobr><a href="#17">2.3 Databases . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11</nobr></div>
- <div style="position:absolute;top:4628;left:130"><nobr><a href="#18">2.4 PersistentDictionaries .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12</nobr></div>
- <div style="position:absolute;top:4652;left:130"><nobr><a href="#19">2.5 Contacts . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13</nobr></div>
- <div style="position:absolute;top:4676;left:130"><nobr><a href="#20">2.6 Calendar . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14</nobr></div>
- <div style="position:absolute;top:4700;left:130"><nobr><a href="#20">2.7 PhoneLogs . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14</nobr></div>
- <div style="position:absolute;top:4724;left:130"><nobr><a href="#21">2.8 Inbox . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15</nobr></div>
- <div style="position:absolute;top:4764;left:108"><nobr><a href="#22">3 Applications, user interfaces, daemons</a></nobr></div>
- <div style="position:absolute;top:4764;left:741"><nobr>16</nobr></div>
- <div style="position:absolute;top:4788;left:130"><nobr><a href="#22">3.1 Application Patterns . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16</nobr></div>
- <div style="position:absolute;top:4812;left:130"><nobr><a href="#23">3.2 ActiveObjects . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17</nobr></div>
- <div style="position:absolute;top:4836;left:130"><nobr><a href="#23">3.3 Blocking . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17</nobr></div>
- <div style="position:absolute;top:4861;left:130"><nobr><a href="#24">3.4 Multitasking . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18</nobr></div>
- <div style="position:absolute;top:4885;left:130"><nobr><a href="#24">3.5 Daemons . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18</nobr></div>
- <div style="position:absolute;top:4909;left:165"><nobr><a href="#24">3.5.1 Simpledaemon . . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18</nobr></div>
- <div style="position:absolute;top:4933;left:165"><nobr><a href="#26">3.5.2 Cooperatingthreads . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20</nobr></div>
- <div style="position:absolute;top:4957;left:165"><nobr><a href="#27">3.5.3 Server threads . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21</nobr></div>
- <div style="position:absolute;top:4981;left:165"><nobr><a href="#28">3.5.4 ThreadsandGUI . . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22</nobr></div>
- <div style="position:absolute;top:5006;left:130"><nobr><a href="#29">3.6 Graphics . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23</nobr></div>
- <div style="position:absolute;top:5050;left:428"><nobr>2</nobr></div>
- </span></font>
- <div style="position:absolute;top:5223;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="5"><b>Page 5</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:5339;left:162"><nobr>TABLE OF CONTENTS</nobr></div>
- <div style="position:absolute;top:5339;left:802"><nobr>3</nobr></div>
- <div style="position:absolute;top:5408;left:162"><nobr><a href="#37">4 Networking</a></nobr></div>
- <div style="position:absolute;top:5408;left:795"><nobr>31</nobr></div>
- <div style="position:absolute;top:5431;left:184"><nobr><a href="#37">4.1 Bluetooth . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31</nobr></div>
- <div style="position:absolute;top:5454;left:219"><nobr><a href="#37">4.1.1 ExternalGPS . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31</nobr></div>
- <div style="position:absolute;top:5492;left:162"><nobr><a href="#41">5 Various</a></nobr></div>
- <div style="position:absolute;top:5492;left:795"><nobr>35</nobr></div>
- <div style="position:absolute;top:5516;left:184"><nobr><a href="#41">5.1 Debugging . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35</nobr></div>
- <div style="position:absolute;top:5554;left:162"><nobr><a href="#42">6 Resources</a></nobr></div>
- <div style="position:absolute;top:5554;left:795"><nobr>36</nobr></div>
- <div style="position:absolute;top:5578;left:184"><nobr><a href="#42">6.1 Python . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36</nobr></div>
- <div style="position:absolute;top:5601;left:184"><nobr><a href="#42">6.2 PyS60 . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36</nobr></div>
- <div style="position:absolute;top:5639;left:162"><nobr><a href="#44">Bibliography</a></nobr></div>
- <div style="position:absolute;top:5639;left:795"><nobr>38</nobr></div>
- </span></font>
- <div style="position:absolute;top:6485;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="6"><b>Page 6</b></a></font></td></tr></tbody></table></div>
- <div style="position:absolute;top:6485;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="7"><b>Page 7</b></a></font></td></tr></tbody></table></div><font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:6787;left:162"><nobr>Introduction</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:6886;left:162"><nobr>This tutorial is meant a supplement to the the ”standard” PyS60 documentation, as listed in Section<a href="#42"> </a>6. We</nobr></div>
- <div style="position:absolute;top:6909;left:162"><nobr>focus in particular on issues that are either poorly documented, poorly demonstrated, or both. We will explain</nobr></div>
- <div style="position:absolute;top:6932;left:162"><nobr>some of the more obscure features in detail, and give bare-bone, but functioning, code examples.</nobr></div>
- <div style="position:absolute;top:6956;left:184"><nobr>We assume the you have a fairly good idea of what PyS60 is, and is determined to use PyS60 in rapid</nobr></div>
- <div style="position:absolute;top:6979;left:162"><nobr>prototyping of your next mobile killer app. You should have browsed the standard intro stuff, see Section <a href="#42">6.</a></nobr></div>
- <div style="position:absolute;top:7002;left:162"><nobr>Furthermore, you should have attended introductory courses in programming and object oriented design. A</nobr></div>
- <div style="position:absolute;top:7026;left:162"><nobr>modest knowledge of Python is an advantage, however, with the above qualifications, you should be able to</nobr></div>
- <div style="position:absolute;top:7049;left:162"><nobr>acquire the nescessary Python fluency on-the-go. Just keep a descent Python tutorial, why not “Diving into</nobr></div>
- <div style="position:absolute;top:7072;left:162"><nobr>Python”[], ready at hand.</nobr></div>
- <div style="position:absolute;top:7096;left:184"><nobr>We also assume that you have established the necessary developer infrastructure, more precisely:</nobr></div>
- <div style="position:absolute;top:7118;left:184"><nobr>• A Series 60 mobile phone with PyS60 installed, including the scripting application</nobr></div>
- <div style="position:absolute;top:7141;left:184"><nobr>• A Python development environment on your lap/desktop</nobr></div>
- <div style="position:absolute;top:7165;left:184"><nobr>• Cable or bluetooth connection for transferring files between mobile and computer</nobr></div>
- <div style="position:absolute;top:7188;left:184"><nobr>• A working bluetooth console, enabling you to run and script stuff in a terminal window on your com-</nobr></div>
- <div style="position:absolute;top:7212;left:199"><nobr>puter, and execute on your phone (sort the developer to</nobr></div>
- <div style="position:absolute;top:7234;left:184"><nobr>• Optionally (since this requires more than the average hassle for Linux/Mac users), a Series 60 emulator</nobr></div>
- <div style="position:absolute;top:7259;left:199"><nobr>(don’t forget to install necessary PyS60 stuff) could come handy.</nobr></div>
- <div style="position:absolute;top:7282;left:162"><nobr>If not, consult the appropriate sources, keep your tongue steady, do what a developer sometimes has to do,</nobr></div>
- <div style="position:absolute;top:7305;left:162"><nobr>and come back.</nobr></div>
- <div style="position:absolute;top:7574;left:482"><nobr>1</nobr></div>
- </span></font>
- <div style="position:absolute;top:7747;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="8"><b>Page 8</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:8045;left:108"><nobr>Chapter 1</nobr></div>
- </span></font>
- <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:8130;left:108"><nobr>Under The Hood</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:8229;left:108"><nobr>Your encounter of the mobile phone as a programmable device might be unfamiliar and frustrating; how do I</nobr></div>
- <div style="position:absolute;top:8252;left:108"><nobr>write the code, what language should I use, how do I compile, how do I test it, how do I deploy it, ...always</nobr></div>
- <div style="position:absolute;top:8276;left:108"><nobr>comparing it to the familiar desk/laptop environment.</nobr></div>
- <div style="position:absolute;top:8300;left:130"><nobr>So, at least for me, on the first encounter: I wanted to get under the hood (and not only under the battery</nobr></div>
- <div style="position:absolute;top:8323;left:108"><nobr>hood) of that toyish looking wanna-be-computer, traverse the filesystem (well, I wasn’t sure if there is such a</nobr></div>
- <div style="position:absolute;top:8347;left:108"><nobr>thing at all) , access system functions, you know, getting to know the playpen.</nobr></div>
- <div style="position:absolute;top:8371;left:130"><nobr>So that’s how we start our PyS60 exploration, by opening the hood.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:8430;left:108"><nobr>1.1 3 x Hello World</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:8475;left:108"><nobr>A few rounds of hello-world should be sufficient for warming up for more serious exploration. Basically,</nobr></div>
- <div style="position:absolute;top:8499;left:108"><nobr>“Hello World!” on PyS60 involves importing the correct GUI module, appuiwf, and call an appropriate</nobr></div>
- <div style="position:absolute;top:8522;left:108"><nobr>GUI function. I’m assuming you’re ready for action, with all of your developer tools all running smoothly.</nobr></div>
- <div style="position:absolute;top:8545;left:108"><nobr>We start as simple as possible; fire up the Python application on the phone, and choose “Interactive console”.</nobr></div>
- <div style="position:absolute;top:8568;left:108"><nobr>Type in the following:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:8600;left:116"><nobr>>>> import appuifw</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:8633;left:108"><nobr>HitS “enter”, ah, well, the “fire”-button, the one in the middle, and continue with the GUI function:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:8664;left:116"><nobr>>>> appuifw . note (u ’ Hello World ! ’ , ’ info ’ )</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:8697;left:108"><nobr>The u in front of the message string performs unicode conversion, every string in the PyS60 GUI is assumed</nobr></div>
- <div style="position:absolute;top:8721;left:108"><nobr>to be unicoded. The next parameter tells the system which type of pop-up box to use (more on this in Section</nobr></div>
- <div style="position:absolute;top:8744;left:108"><nobr><a href="#22">3</a>. Now the magic should happen, and you should see some thing like Figure 1.1:</nobr></div>
- <div style="position:absolute;top:8768;left:130"><nobr>If you really managed to sms-style typing these statements without critically raising your blood pressure</nobr></div>
- <div style="position:absolute;top:8792;left:108"><nobr>levels, well, congratulations! Otherwise, you have four options:</nobr></div>
- <div style="position:absolute;top:8836;left:428"><nobr>2</nobr></div>
- </span></font>
- <div style="position:absolute;top:9009;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="9"><b>Page 9</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:9125;left:162"><nobr>1.1. 3 x Hello World</nobr></div>
- <div style="position:absolute;top:9125;left:802"><nobr>3</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
- <div style="position:absolute;top:9513;left:337"><nobr>Figure 1.1: GUI-style Hello World with two statements</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:9559;left:184"><nobr>• If you want to stay mobile: Dust off your bluetooth collapsible keyboard, ideal for a relaxed coding</nobr></div>
- <div style="position:absolute;top:9583;left:199"><nobr>session (Figure<a href="#10"> 1.2</a>). You can also install a dedicated Python editor(!) to make your coding even more</nobr></div>
- <div style="position:absolute;top:9606;left:199"><nobr>efficient<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>.</nobr></div>
- <div style="position:absolute;top:9628;left:184"><nobr>• If you are close to your computer: Start the bluetooth console, making it possible to run code on the</nobr></div>
- <div style="position:absolute;top:9653;left:199"><nobr>device from your computer.</nobr></div>
- <div style="position:absolute;top:9675;left:184"><nobr>• Or, if you want to ”cheat”, or do not have access to a device: Use the emulator. However: remember,</nobr></div>
- <div style="position:absolute;top:9700;left:199"><nobr>there’s a lot of things the emulator can’t emulate, for instance the camera module, or the messaging</nobr></div>
- <div style="position:absolute;top:9723;left:199"><nobr>stuff.</nobr></div>
- <div style="position:absolute;top:9745;left:184"><nobr>• Write scripts in your favorite editor, preferably one with python support (e.g., on windows, the IDLE</nobr></div>
- <div style="position:absolute;top:9769;left:199"><nobr>that is bundled with the most common python distro). When you have convinced yourself that the code</nobr></div>
- <div style="position:absolute;top:9793;left:199"><nobr>will work, transfer it to the phone, either by Bluetooth or cable, then run it to check if it’s working.</nobr></div>
- <div style="position:absolute;top:9816;left:184"><nobr>Choose the style that best fits your mood, situation and purpose: the bluetooth console is good for informal</nobr></div>
- <div style="position:absolute;top:9839;left:162"><nobr>exploration, emulator + IDE is probably best for larger projects. Anyway, you should try to separate symbian</nobr></div>
- <div style="position:absolute;top:9863;left:162"><nobr>specific code (e.g., GUI stuff) from general purpose pieces. Then you could decide in runtime which platform</nobr></div>
- <div style="position:absolute;top:9886;left:162"><nobr>you’re running the code on, and choose the appropriate files, methods or snippets accordingly.</nobr></div>
- <div style="position:absolute;top:9910;left:184"><nobr>You will soon feel the urge for running larger code segments on the phone, and further, making modules</nobr></div>
- <div style="position:absolute;top:9933;left:162"><nobr>that could be reused, all in good modularization tradition. And, in the longer run, you are bound to start start</nobr></div>
- <div style="position:absolute;top:9956;left:162"><nobr>using the object-oriented features of Python.</nobr></div>
- <div style="position:absolute;top:9980;left:184"><nobr>So, before really opening the hood, in the next section we go through a few templates that can help us</nobr></div>
- <div style="position:absolute;top:10003;left:162"><nobr>building those wonderful next generation mobile killer apps. However, to justify your choice of programming</nobr></div>
- <div style="position:absolute;top:10026;left:162"><nobr>platform for rapid mobile prototyping, let’s consider “Hello World” in Java and C++, which are the most</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:10053;left:178"><nobr>1<a href="http://homepage.rub.de/Arkadiusz.Wahlig/Ped"></a><font style="font-size:9px"><a href="http://homepage.rub.de/Arkadiusz.Wahlig/Ped">http://homepage.rub.de/Arkadiusz.Wahlig/Ped</a></font></nobr></div>
- </span></font>
- <div style="position:absolute;top:10271;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="10"><b>Page 10</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:10387;left:108"><nobr>4</nobr></div>
- <div style="position:absolute;top:10387;left:589"><nobr>Chapter 1. Under The Hood</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
- <div style="position:absolute;top:10718;left:350"><nobr>Figure 1.2: Pool programming</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:10763;left:108"><nobr>commonly used alternatives for Symbian developers.</nobr></div>
- <div style="position:absolute;top:10786;left:130"><nobr>We start with the Java MIDP (and remember, you have to compile before running it in the emulator or</nobr></div>
- <div style="position:absolute;top:10809;left:108"><nobr>deploying it on the device (and there is not any equivalent to bluetooth console):</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:10838;left:120"><nobr>import javax . microedition . midlet . ∗ ;</nobr></div>
- <div style="position:absolute;top:10856;left:120"><nobr>import javax . microedition . lcdui . ∗ ;</nobr></div>
- <div style="position:absolute;top:10893;left:120"><nobr>public class HelloWorld extends MIDlet implements CommandListener {</nobr></div>
- <div style="position:absolute;top:10911;left:149"><nobr>private Command exitCommand ;</nobr></div>
- <div style="position:absolute;top:10930;left:149"><nobr>private TextBox tbox ;</nobr></div>
- <div style="position:absolute;top:10967;left:149"><nobr>public HelloWorld () {</nobr></div>
- <div style="position:absolute;top:10985;left:177"><nobr>exitCommand = new Command ( ” E x i t ” , Command . EXIT , 1 ) ;</nobr></div>
- <div style="position:absolute;top:11004;left:178"><nobr>tbox = new TextBox(”Hello world MIDlet”, ”Hello World!”, 25, 0);</nobr></div>
- <div style="position:absolute;top:11022;left:178"><nobr>tbox . addCommand ( exitCommand ) ;</nobr></div>
- <div style="position:absolute;top:11041;left:178"><nobr>tbox . setCommandListener ( this ) ;</nobr></div>
- <div style="position:absolute;top:11058;left:148"><nobr>}</nobr></div>
- <div style="position:absolute;top:11096;left:149"><nobr>protected void startApp () {</nobr></div>
- <div style="position:absolute;top:11115;left:178"><nobr>Display . getDisplay ( this ). setCurrent ( tbox );</nobr></div>
- <div style="position:absolute;top:11132;left:148"><nobr>}</nobr></div>
- <div style="position:absolute;top:11170;left:149"><nobr>protected void pauseApp ( ) {}</nobr></div>
- <div style="position:absolute;top:11188;left:149"><nobr>protected void destroyApp ( boolean bool ) {}</nobr></div>
- <div style="position:absolute;top:11225;left:149"><nobr>public void commandAction(Command cmd, Displayable disp) {</nobr></div>
- <div style="position:absolute;top:11244;left:178"><nobr>i f (cmd == exitCommand) {</nobr></div>
- <div style="position:absolute;top:11262;left:206"><nobr>destroyApp ( false ) ;</nobr></div>
- <div style="position:absolute;top:11281;left:207"><nobr>notifyDestroyed ();</nobr></div>
- <div style="position:absolute;top:11298;left:176"><nobr>}</nobr></div>
- <div style="position:absolute;top:11317;left:148"><nobr>}</nobr></div>
- </span></font>
- <div style="position:absolute;top:11533;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="11"><b>Page 11</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:11649;left:162"><nobr>1.2. System Info</nobr></div>
- <div style="position:absolute;top:11649;left:802"><nobr>5</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:11719;left:173"><nobr>}</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:11749;left:162"><nobr>Now, for something completely different; for the Symbian C++ Hello World, the following files are needed</nobr></div>
- <div style="position:absolute;top:11773;left:162"><nobr>for building the application:</nobr></div>
- <div style="position:absolute;top:11795;left:184"><nobr>• bld.inf</nobr></div>
- <div style="position:absolute;top:11818;left:184"><nobr>• helloworld.h</nobr></div>
- <div style="position:absolute;top:11842;left:184"><nobr>• helloworld.hrh</nobr></div>
- <div style="position:absolute;top:11865;left:184"><nobr>• helloworld.mmp</nobr></div>
- <div style="position:absolute;top:11888;left:184"><nobr>• helloworld.rss</nobr></div>
- <div style="position:absolute;top:11912;left:184"><nobr>• helloworld application.cpp</nobr></div>
- <div style="position:absolute;top:11935;left:184"><nobr>• helloworld appui.cpp</nobr></div>
- <div style="position:absolute;top:11958;left:184"><nobr>• helloworld appview.cpp</nobr></div>
- <div style="position:absolute;top:11981;left:184"><nobr>• helloworld document.cpp</nobr></div>
- <div style="position:absolute;top:12005;left:184"><nobr>• helloworld main.cpp</nobr></div>
- <div style="position:absolute;top:12029;left:162"><nobr>Say no more.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:12083;left:162"><nobr>1.2 System Info</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:12126;left:162"><nobr>The sysinfo module supplies you with a lot of under-the-hood stuff. Now, how much memory is there</nobr></div>
- <div style="position:absolute;top:12149;left:162"><nobr>around<a href="#1"></a><font style="font-size:8px"><a href="#1">2</a></font><a href="#1"></a>?</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:12178;left:170"><nobr>>>> import sysinfo</nobr></div>
- <div style="position:absolute;top:12197;left:170"><nobr>>>> sysinfo . total ram ()</nobr></div>
- <div style="position:absolute;top:12215;left:174"><nobr>58720256</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:12245;left:162"><nobr>And free memory?</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:12273;left:170"><nobr>>>> sysinfo.free ram()</nobr></div>
- <div style="position:absolute;top:12292;left:174"><nobr>21192704</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:12322;left:162"><nobr>We launch the map application, and check the RAM use again:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:12351;left:174"><nobr>19361792</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:12380;left:162"><nobr>Let’s use python as a calculator and find out how much RAM the map app eats:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:12409;left:170"><nobr>>>> (21192704 −19361792)/(1024∗1024.0)</nobr></div>
- <div style="position:absolute;top:12427;left:174"><nobr>1.746094</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:12457;left:162"><nobr>OK, 1.7 Mb, not bad (note the decimal, ”.0”, without it, python would do perform integer division).</nobr></div>
- <div style="position:absolute;top:12480;left:184"><nobr>Battery capacity is a problem on mobile devices, and it could be handy to check it programmatically (0-7</nobr></div>
- <div style="position:absolute;top:12504;left:162"><nobr>on earlier devices, 0-100 on new ones):</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:12532;left:170"><nobr>>>> sysinfo . battery ()</nobr></div>
- <div style="position:absolute;top:12551;left:173"><nobr>100</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:12577;left:178"><nobr>2<font style="font-size:9px">Run on a Nokia N95</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:12795;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="12"><b>Page 12</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:12911;left:108"><nobr>6</nobr></div>
- <div style="position:absolute;top:12911;left:589"><nobr>Chapter 1. Under The Hood</nobr></div>
- <div style="position:absolute;top:12980;left:108"><nobr>Display size:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:13008;left:116"><nobr>>>> sysinfo . display pixels ()</nobr></div>
- <div style="position:absolute;top:13027;left:120"><nobr>(240 , 320)</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:13056;left:108"><nobr>Signal strength may vary wildly when moving around, in partiular in buildings and rural areas, and it could be</nobr></div>
- <div style="position:absolute;top:13080;left:108"><nobr>reasonable to give the user a warning if he is going to start a major network transaction with a bad connection.</nobr></div>
- <div style="position:absolute;top:13103;left:108"><nobr>The first function uses the range 1-7, the last one returns signal strenght in dBm. A 3 dBm increase roughly</nobr></div>
- <div style="position:absolute;top:13126;left:108"><nobr>doubles the strength.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:13155;left:116"><nobr>>>> sysinfo . signal bars ()</nobr></div>
- <div style="position:absolute;top:13173;left:119"><nobr>7</nobr></div>
- <div style="position:absolute;top:13191;left:116"><nobr>>>> sysinfo.signal dbm()</nobr></div>
- <div style="position:absolute;top:13210;left:119"><nobr>72</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:13239;left:108"><nobr>Signal strenght is also useful in cell tower stumbling, i.e., when you try to estimate your location from cell</nobr></div>
- <div style="position:absolute;top:13263;left:108"><nobr>tower information, which you obtain with the location module<a href="#1"></a><font style="font-size:8px"><a href="#1">3</a></font><a href="#1"></a>:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:13291;left:116"><nobr>>>> import location</nobr></div>
- <div style="position:absolute;top:13310;left:116"><nobr>>>> print location.gsm location()</nobr></div>
- <div style="position:absolute;top:13328;left:119"><nobr>None</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:13388;left:108"><nobr>1.3 Filesystem</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:13431;left:108"><nobr>Symbian phones sport several drives. We explore them by using the e32 and os modules:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:13460;left:116"><nobr>>>> import e32 , os</nobr></div>
- <div style="position:absolute;top:13478;left:116"><nobr>>>> drives = e32 . d r i v e l i s t ( )</nobr></div>
- <div style="position:absolute;top:13497;left:116"><nobr>>>> print drives</nobr></div>
- <div style="position:absolute;top:13515;left:120"><nobr>[u’C: ’ ,u’D: ’ ,u’E: ’ ,u’Z: ’]</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:13545;left:108"><nobr>What are these drives? Let’s check for content:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:13573;left:120"><nobr>for d in drives :</nobr></div>
- <div style="position:absolute;top:13592;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:13592;left:178"><nobr>print ’DRIVE ’ + d + ’ . . . . . . . . . . . . . . . . . . . : ’</nobr></div>
- <div style="position:absolute;top:13610;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:13610;left:178"><nobr>print os. listdir (d)</nobr></div>
- <div style="position:absolute;top:13629;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:13647;left:119"><nobr>DRIVE C : . . . . . . . . . . . . . . . . . . . :</nobr></div>
- <div style="position:absolute;top:13666;left:120"><nobr>[ ’cache ’ , ’Data ’ , ’ feeds view template . html ’ , ’ Predic ’ , ’ Private ’ , ’RESOURCE’ , ’</nobr></div>
- <div style="position:absolute;top:13684;left:119"><nobr>SYS’ , ’System ’ , ’ video config ’ ]</nobr></div>
- <div style="position:absolute;top:13702;left:119"><nobr>DRIVE D : . . . . . . . . . . . . . . . . . . . :</nobr></div>
- <div style="position:absolute;top:13721;left:120"><nobr>[ ’ Private ’]</nobr></div>
- <div style="position:absolute;top:13739;left:119"><nobr>DRIVE E : . . . . . . . . . . . . . . . . . . . :</nobr></div>
- <div style="position:absolute;top:13758;left:120"><nobr>[ ’ . . Trashes ’ , ’ . Trashes ’ , ’ ActivityMonitor ’ , ’ cities ’ , ’Data ’ , ’Documents ’ ,</nobr></div>
- <div style="position:absolute;top:13776;left:121"><nobr>’Images ’ , ’ lifeblog ’ , ’My Videos ’ , ’nmea info . py ’ , ’Others ’ , ’pb ’ , ’ Private ’ ,</nobr></div>
- <div style="position:absolute;top:13795;left:121"><nobr>’Python ’ , ’qf ’ , ’ resource ’ , ’Sounds ’ , ’ SportsTracker ’ , ’ sys ’ , ’system ’ , ’Videos ’ ]</nobr></div>
- <div style="position:absolute;top:13813;left:119"><nobr>DRIVE Z : . . . . . . . . . . . . . . . . . . . :</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:13839;left:124"><nobr>3<font style="font-size:9px">Requires signing, more on this later!</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:14057;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="13"><b>Page 13</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:14173;left:162"><nobr>1.3. Filesystem</nobr></div>
- <div style="position:absolute;top:14173;left:802"><nobr>7</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:14244;left:174"><nobr>[ ’ c i t i e s ’ , ’ data ’ , ’DevIcon . f i l ’ , ’DevLogo . f i l ’ , ’epoc32 ’ ,</nobr></div>
- <div style="position:absolute;top:14262;left:175"><nobr>’feeds view template.html’, ’private’, ’resource’, ’sys’, ’System’]</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:14290;left:162"><nobr>Let’s have a peek in the Images directory on E:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:14318;left:170"><nobr>>>> print os. listdir (u’E:\ Images ’ )</nobr></div>
- <div style="position:absolute;top:14336;left:174"><nobr>[ ’ PAlbTN ’ , ’200701 ’ , ’200704 ’ , ’200705 ’ , ’200706 ’ , ’200707 ’ , ’200708 ’ , ’200711 ’</nobr></div>
- <div style="position:absolute;top:14355;left:175"><nobr>, ’200712 ’ , ’200801 ’ , ’200802 ’ , ’GPS−1182932823. jpg ’ , ’GPS−1182932844. jpg ’ , ’GPS</nobr></div>
- <div style="position:absolute;top:14372;left:174"><nobr>−1182932855. jpg ’ , ’Halden . jpg ’ , ’ Kart . jpg ’ , ’mapdevices . jpg ’ , ’ opera . jpg ’ , ’ pict</nobr></div>
- <div style="position:absolute;top:14392;left:174"><nobr>ure1 . jpg ’ , ’Snap ’ ]</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:14420;left:162"><nobr>And what’s on the Private directory on E:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:14447;left:170"><nobr>>>> print os. listdir (u’D:\ Private ’)</nobr></div>
- <div style="position:absolute;top:14466;left:174"><nobr>Traceback (most recent call last ):</nobr></div>
- <div style="position:absolute;top:14484;left:189"><nobr>File ”<console>”, line 1, in ?</nobr></div>
- <div style="position:absolute;top:14503;left:174"><nobr>OSError : [ Errno −46] : ’D:\\ Private ’</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:14531;left:184"><nobr>Well, what did you expect, the sign said ”Private”, that usual means stay away!</nobr></div>
- <div style="position:absolute;top:14554;left:184"><nobr>So, the common mapping of Symbian drives are</nobr></div>
- <div style="position:absolute;top:14576;left:184"><nobr>• C: Main ”disk”, or rather flash memory. No reason to mess around here, leave it to the device, installed</nobr></div>
- <div style="position:absolute;top:14601;left:199"><nobr>software and operator related stuff.</nobr></div>
- <div style="position:absolute;top:14623;left:184"><nobr>• D: RAM memory (do not tamper!)</nobr></div>
- <div style="position:absolute;top:14646;left:184"><nobr>• E: Memory card: This is the ”safe” play pen area, and also by far the area with largest capacity (today</nobr></div>
- <div style="position:absolute;top:14671;left:199"><nobr>typically 1 GB)</nobr></div>
- <div style="position:absolute;top:14693;left:184"><nobr>• Z: ROM memory: Read only system files, may only be changed by flashing software, e.g., when you</nobr></div>
- <div style="position:absolute;top:14717;left:199"><nobr>update the firmware.</nobr></div>
- <div style="position:absolute;top:14741;left:162"><nobr>Try to connect to your computer with a cable, and and Y probably appears.</nobr></div>
- <div style="position:absolute;top:14764;left:184"><nobr>Citing from PyS60 API doc:</nobr></div>
- <div style="position:absolute;top:14795;left:199"><nobr>“Some OS level concepts to which the standard os library module offers an interface do not</nobr></div>
- <div style="position:absolute;top:14818;left:199"><nobr>exist as such in Symbian OS environment. An example of this is the concept of current working</nobr></div>
- <div style="position:absolute;top:14842;left:199"><nobr>directory.”</nobr></div>
- <div style="position:absolute;top:14873;left:162"><nobr>Really? Consider the following statements executed on a N95:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:14900;left:170"><nobr>>>> import os</nobr></div>
- <div style="position:absolute;top:14919;left:170"><nobr>>>> print ’Here we are: ’ + os.path.abspath(’.’)</nobr></div>
- <div style="position:absolute;top:14937;left:174"><nobr>Here we are: c:\</nobr></div>
- <div style="position:absolute;top:14956;left:170"><nobr>>>> print ’Or, here?: ’ + os.getcwd()</nobr></div>
- <div style="position:absolute;top:14974;left:173"><nobr>Or , here ?: E:\\ Private \\2000b1a5\\</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:15002;left:184"><nobr>Let’s try walking around, what about changing directory, or rather drive:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:15030;left:170"><nobr>>>> chdir(”C:\ Data”)</nobr></div>
- <div style="position:absolute;top:15048;left:170"><nobr>>>> print os . path . abspath ( ’ . ’ )</nobr></div>
- <div style="position:absolute;top:15067;left:174"><nobr>c :\</nobr></div>
- <div style="position:absolute;top:15085;left:170"><nobr>>>> print os . getcwd ()</nobr></div>
- <div style="position:absolute;top:15104;left:172"><nobr>C:\\ Data\\</nobr></div>
- </span></font>
- <div style="position:absolute;top:15319;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="14"><b>Page 14</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:15435;left:108"><nobr>8</nobr></div>
- <div style="position:absolute;top:15435;left:589"><nobr>Chapter 1. Under The Hood</nobr></div>
- <div style="position:absolute;top:15504;left:108"><nobr>OK, we’re allowed walking around, however, the ’.’ yields the C drive, no matter where we are.</nobr></div>
- <div style="position:absolute;top:15527;left:130"><nobr>Traversing the file system is an essential ability, for finding files, or, more relevant, performing actions,</nobr></div>
- <div style="position:absolute;top:15550;left:108"><nobr>possibly complex and conditional, on selected files or directories. To walk around, we use os.path.walk,</nobr></div>
- <div style="position:absolute;top:15574;left:108"><nobr>taking a customized callback function to be executed for each visited directory. Here’s the short syntactical</nobr></div>
- <div style="position:absolute;top:15597;left:108"><nobr>explanation:</nobr></div>
- <div style="position:absolute;top:15633;left:145"><nobr>walk(path, visit, arg):</nobr></div>
- <div style="position:absolute;top:15662;left:145"><nobr>Calls the function visit with arguments (arg, dirname, names) for each directory in the di-</nobr></div>
- <div style="position:absolute;top:15685;left:145"><nobr>rectory tree rooted at path (including path itself, if it is a directory). The argument dirname</nobr></div>
- <div style="position:absolute;top:15708;left:145"><nobr>specifies the visited directory, the argument names lists the files in the directory (gotten from</nobr></div>
- <div style="position:absolute;top:15731;left:145"><nobr>os.listdir(dirname)). The visit function may modify names to influence the set of directories</nobr></div>
- <div style="position:absolute;top:15755;left:145"><nobr>visited below dirname, e.g., to avoid visiting certain parts of the tree.</nobr></div>
- <div style="position:absolute;top:15790;left:108"><nobr>And here is a PyS60 example, printing all directories on the device:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:15819;left:120"><nobr>import e32</nobr></div>
- <div style="position:absolute;top:15838;left:120"><nobr>import os</nobr></div>
- <div style="position:absolute;top:15875;left:121"><nobr>class Main :</nobr></div>
- <div style="position:absolute;top:15912;left:149"><nobr>def</nobr></div>
- <div style="position:absolute;top:15912;left:193"><nobr>init</nobr></div>
- <div style="position:absolute;top:15912;left:235"><nobr>( self ):</nobr></div>
- <div style="position:absolute;top:15930;left:178"><nobr>self . drives ()</nobr></div>
- <div style="position:absolute;top:15967;left:149"><nobr>def drives ( self ):</nobr></div>
- <div style="position:absolute;top:15986;left:178"><nobr>drives = e32 . d r i v e l i s t ( )</nobr></div>
- <div style="position:absolute;top:16004;left:178"><nobr>for drive in drives :</nobr></div>
- <div style="position:absolute;top:16023;left:206"><nobr>os . path . walk ( drive , s e l f . l i s t f i l e s , None )</nobr></div>
- <div style="position:absolute;top:16059;left:149"><nobr>def l i s t f i l e s ( arg , dirname , fnames ) :</nobr></div>
- <div style="position:absolute;top:16078;left:178"><nobr>print dirname</nobr></div>
- <div style="position:absolute;top:16115;left:121"><nobr>i f</nobr></div>
- <div style="position:absolute;top:16115;left:154"><nobr>name</nobr></div>
- <div style="position:absolute;top:16115;left:205"><nobr>== ’ main</nobr></div>
- <div style="position:absolute;top:16115;left:293"><nobr>’:</nobr></div>
- <div style="position:absolute;top:16133;left:148"><nobr>main = Main()</nobr></div>
- </span></font>
- <div style="position:absolute;top:16581;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="15"><b>Page 15</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:16878;left:162"><nobr>Chapter 2</nobr></div>
- </span></font>
- <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:16962;left:162"><nobr>Storing Stuff</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:17060;left:162"><nobr>There’s not much interesting you could without storing data in some way or another. There are basically three</nobr></div>
- <div style="position:absolute;top:17084;left:162"><nobr>ways of persisting data with PyS60: Using files, pickling objects and through databases. Databases come in</nobr></div>
- <div style="position:absolute;top:17107;left:162"><nobr>these flavors: SQL (lite) db, dictionary db, calender db, and the contacts db.</nobr></div>
- <div style="position:absolute;top:17130;left:184"><nobr>In addition, the device stores a variety of log information, like the last incoming calls etc., and to the</nobr></div>
- <div style="position:absolute;top:17154;left:162"><nobr>programmer this represents a valuable resource.</nobr></div>
- <div style="position:absolute;top:17177;left:184"><nobr>Last, but not least, we have the inbox of messages: sms, mms, bluetooth etc.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:17230;left:162"><nobr>2.1 Files</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:17273;left:162"><nobr>To use files, you have to be able to navigate in the file system, to create and remove directories and files, and</nobr></div>
- <div style="position:absolute;top:17296;left:162"><nobr>write to and read from the files, both in ascii and binary fashion. In PyS60 you create, open, close, write to</nobr></div>
- <div style="position:absolute;top:17320;left:162"><nobr>and read from files as in plain Python, likewise with making and deleting directories, see any Python tutorial,</nobr></div>
- <div style="position:absolute;top:17343;left:162"><nobr>e.g., ??.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:17396;left:162"><nobr>2.2 Pickling, and how to easily extend PyS60</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:17439;left:162"><nobr>Pickling is the Python way of serializing objects. Class instances are transformed to a platform independent</nobr></div>
- <div style="position:absolute;top:17462;left:162"><nobr>bytestream that can be written to a file, and later read from that file to construct a new instance of that class</nobr></div>
- <div style="position:absolute;top:17486;left:162"><nobr>in the exact same state, i.e., with the same values of the variables and methods as the original.</nobr></div>
- <div style="position:absolute;top:17509;left:184"><nobr>However, the pickle module is not part of PyS60, but don’t despair. Many Python modules may be directly</nobr></div>
- <div style="position:absolute;top:17532;left:162"><nobr>imported, or deployed, on the PyS60 platform by loading the corresponding.py file as a module. Depending</nobr></div>
- <div style="position:absolute;top:17556;left:162"><nobr>on the dependencies (no pun intended?), it may work out of the box, or, some minor might do the trick, ...or</nobr></div>
- <div style="position:absolute;top:17579;left:162"><nobr>not. Let’s try it out.</nobr></div>
- <div style="position:absolute;top:17602;left:184"><nobr>You can grab the module (only one file, pickle.py) from the Python installation on your computer,</nobr></div>
- <div style="position:absolute;top:17626;left:162"><nobr>or from the source available from<a href="http://python.org"> python.org. </a>However, the pickle module from recent releases will</nobr></div>
- <div style="position:absolute;top:17670;left:482"><nobr>9</nobr></div>
- </span></font>
- <div style="position:absolute;top:17843;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="16"><b>Page 16</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:17959;left:108"><nobr>10</nobr></div>
- <div style="position:absolute;top:17959;left:613"><nobr>Chapter 2. Storing Stuff</nobr></div>
- <div style="position:absolute;top:18028;left:108"><nobr>not work without major hassle, so rip it from a Python 2.2<a href="#1"></a><font style="font-size:8px"><a href="#1">1 </a></font>installation. Transfer it to your phone, e.g.,</nobr></div>
- <div style="position:absolute;top:18051;left:108"><nobr>over bluetooth, and install as a module<a href="#1"></a><font style="font-size:8px"><a href="#1">2 </a></font>If you want to try it in the emulator on a PC, copy the pickle file</nobr></div>
- <div style="position:absolute;top:18074;left:108"><nobr>to the Symbian\.9.2\.S60 3rd FP1\.Epoc32\.winscw\.c\.resource folder<a href="#1"></a><font style="font-size:8px"><a href="#1">3 </a></font>And now, some</nobr></div>
- <div style="position:absolute;top:18098;left:108"><nobr>pickling code. First, the custom class definition in the file answer.py, imported into your environment as</nobr></div>
- <div style="position:absolute;top:18121;left:108"><nobr>a module:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18152;left:121"><nobr>class TheAnswer :</nobr></div>
- <div style="position:absolute;top:18170;left:149"><nobr>def</nobr></div>
- <div style="position:absolute;top:18170;left:193"><nobr>init</nobr></div>
- <div style="position:absolute;top:18170;left:235"><nobr>( self ):</nobr></div>
- <div style="position:absolute;top:18189;left:178"><nobr>self.foo = u’The answer’</nobr></div>
- <div style="position:absolute;top:18207;left:178"><nobr>self.bar = 42</nobr></div>
- <div style="position:absolute;top:18225;left:149"><nobr>def meaning( self ):</nobr></div>
- <div style="position:absolute;top:18244;left:178"><nobr>print self.foo + ” is ” + str(self.bar)</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:18276;left:108"><nobr>Here is the application code:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18307;left:120"><nobr>import os</nobr></div>
- <div style="position:absolute;top:18325;left:120"><nobr>import pickle</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18344;left:119"><nobr># import custom class definition</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18362;left:120"><nobr>import answer</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18399;left:119"><nobr># initialize answer object</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18417;left:120"><nobr>answer = answer.TheAnswer()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18436;left:119"><nobr># get answer</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18454;left:120"><nobr>answer . meaning ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18473;left:119"><nobr># modify answer</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18491;left:120"><nobr>answer.bar = 43</nobr></div>
- <div style="position:absolute;top:18528;left:120"><nobr>path = <font color="#4c4c4c">#set your destination directory here</font></nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18547;left:119"><nobr># construct path to pickle file</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18565;left:120"><nobr>f = path + ” t e s t . pickle ”</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18584;left:119"><nobr># open a file to save the pickled answer instance</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18602;left:121"><nobr>picklefile = open(f, ’w’)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18621;left:119"><nobr># pickle it</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18639;left:121"><nobr>p i c k l e . dump ( answer , p i c k l e f i l e )</nobr></div>
- <div style="position:absolute;top:18657;left:121"><nobr>picklefile . close ()</nobr></div>
- <div style="position:absolute;top:18676;left:121"><nobr>picklefile = open(f, ’r’)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18694;left:119"><nobr># unpickle the answer</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18713;left:120"><nobr>answer2 = pickle.load(picklefile)</nobr></div>
- <div style="position:absolute;top:18731;left:121"><nobr>picklefile . close ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:18750;left:119"><nobr># check the answer, should be 43</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18768;left:120"><nobr>answer2 . meaning ()</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:18800;left:108"><nobr>For more information on pickling, see the Python docs<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:18829;left:124"><nobr>1<font style="font-size:9px">PyS60 is based on Python 2.2</font></nobr></div>
- <div style="position:absolute;top:18844;left:124"><nobr>2<font style="font-size:9px">On 3rd. edition phones you have to copy the file manually to CHECK PATH!</font></nobr></div>
- <div style="position:absolute;top:18859;left:124"><nobr>3<font style="font-size:9px">CHECK: In the emulator, if you try to pickle an instance of an object defined in the file where the pickling is performed, an exception</font></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:18875;left:108"><nobr>is raised. However, implementing the class in a separate module file, and importing the class, works OK.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:18887;left:124"><nobr>4<a href="http://docs.python.org/lib/node317.html"></a><font style="font-size:9px"><a href="http://docs.python.org/lib/node317.html">http://docs.python.org/lib/node317.html</a></font></nobr></div>
- </span></font>
- <div style="position:absolute;top:19105;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="17"><b>Page 17</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:19221;left:162"><nobr>2.3. Databases</nobr></div>
- <div style="position:absolute;top:19221;left:795"><nobr>11</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:19285;left:162"><nobr>2.3 Databases</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:19329;left:162"><nobr>At first thought, it seems like overkill to have an onboard database on your phone. But, rethinking, there are</nobr></div>
- <div style="position:absolute;top:19352;left:162"><nobr>quite a number of application scenarios requiring access to complex information repositories. In many cases,</nobr></div>
- <div style="position:absolute;top:19375;left:162"><nobr>the obvious solution is to implement the database stuff server side, however, remember that your phone might</nobr></div>
- <div style="position:absolute;top:19398;left:162"><nobr>be offline in periods, or it could be too costly with frequent data transmissions.</nobr></div>
- <div style="position:absolute;top:19422;left:184"><nobr>Anyway, since the Symbian core uses a database to structure, store and manipulate various log data, like</nobr></div>
- <div style="position:absolute;top:19445;left:162"><nobr>incoming calls, contact lists, calendar, etc., this database engine is made available for the programmer in the</nobr></div>
- <div style="position:absolute;top:19469;left:162"><nobr>e32db module. It supports relational data base manipulation with “restricted SQL syntax”<a href="#1"></a><font style="font-size:8px"><a href="#1">5</a></font><a href="#1"></a>.</nobr></div>
- <div style="position:absolute;top:19492;left:184"><nobr>There are two main classes, Dbms and Db view. The first performs high level operations, like creating,</nobr></div>
- <div style="position:absolute;top:19515;left:162"><nobr>opening, closing, committing and executing SQL statements that in some way affects the database. The other</nobr></div>
- <div style="position:absolute;top:19538;left:162"><nobr>class let you issue SQL select statements, yielding database views, which in turn gives you access to the</nobr></div>
- <div style="position:absolute;top:19562;left:162"><nobr>rows and columns produced by the query.</nobr></div>
- <div style="position:absolute;top:19585;left:184"><nobr>Here is a minimalistic, but working, example that covers the essential functionality:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:19612;left:174"><nobr>import os</nobr></div>
- <div style="position:absolute;top:19630;left:174"><nobr>import e32 , e32db</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:19649;left:173"><nobr># Get instances of the database and database view classes</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:19667;left:173"><nobr>dbm = e32db.Dbms()</nobr></div>
- <div style="position:absolute;top:19686;left:173"><nobr>dbv = e32db.Db view()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:19704;left:173"><nobr># Build a full path to the DB</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:19723;left:174"><nobr>path = <font color="#4c4c4c"># Your path here</font></nobr></div>
- <div style="position:absolute;top:19741;left:173"><nobr>dbname = u ’ t e s t . db ’</nobr></div>
- <div style="position:absolute;top:19760;left:174"><nobr>dbpath = path+dbname</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:19778;left:173"><nobr># Open the database</nobr></div>
- <div style="position:absolute;top:19797;left:173"><nobr># If it ’s not already there , create , define and populate it</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:19815;left:174"><nobr>try :</nobr></div>
- <div style="position:absolute;top:19834;left:201"><nobr>dbm. open ( unicode ( dbpath ))</nobr></div>
- <div style="position:absolute;top:19852;left:174"><nobr>except :</nobr></div>
- <div style="position:absolute;top:19870;left:201"><nobr>dbm. create ( unicode ( dbpath ))</nobr></div>
- <div style="position:absolute;top:19889;left:201"><nobr>dbm. open ( unicode ( dbpath ))</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:19908;left:202"><nobr># Create a database with fields for an ID, a name, and a bluetooth address</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:19926;left:201"><nobr>dbm.execute(u’create table bt (id integer , name varchar , btaddr varchar)’)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:19944;left:202"><nobr># Populate database</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:19963;left:201"><nobr>dbm. execute (u ’ insert into bt values (1 , \ ’name 1\ ’ , \ ’bt1 \ ’) ’ )</nobr></div>
- <div style="position:absolute;top:19981;left:201"><nobr>dbm. execute (u ’ insert into bt values (2 , \ ’name 2\ ’ , \ ’bt2 \ ’) ’ )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20000;left:173"><nobr># Prepare a database view by selecting all rows</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20018;left:173"><nobr>dbv . prepare (dbm, u ’ select ∗ from bt ’ )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20037;left:173"><nobr># Get the number of columns (yeah, ok, we now it is three :−)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20055;left:174"><nobr>col num = dbv.col count()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20074;left:173"><nobr># Iterate over all rows in the view</nobr></div>
- <div style="position:absolute;top:20092;left:173"><nobr># Start with setting the database view cursor on first row</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20110;left:173"><nobr>dbv. first line ()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:20135;left:178"><nobr>5<font style="font-size:9px">As always, when the PyS60 API documentation is a bit sketchy, you will find things in more detail in the S60 SDK documentation.</font></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20152;left:162"><nobr>Remember that PyS60 , in essence, is a thin wrapping over the native C++ core.</nobr></div>
- </span></font>
- <div style="position:absolute;top:20367;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="18"><b>Page 18</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:20483;left:108"><nobr>12</nobr></div>
- <div style="position:absolute;top:20483;left:613"><nobr>Chapter 2. Storing Stuff</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20554;left:120"><nobr>for i in range ( dbv . c o u n t l i n e ( ) ) :</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20572;left:148"><nobr># Get the current row</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20591;left:148"><nobr>dbv. get line ()</nobr></div>
- <div style="position:absolute;top:20609;left:150"><nobr>result = ’’</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20628;left:148"><nobr># Iterate over the columns</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20646;left:149"><nobr>for j in range(col num):</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20665;left:177"><nobr># Store the fields as strings</nobr></div>
- <div style="position:absolute;top:20683;left:177"><nobr># Remember that columns are indexed from 1, not 0</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20701;left:178"><nobr>result += ’ ’+str(dbv.col(j+1))</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20720;left:148"><nobr># This should yield the stuff we inserted</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20738;left:149"><nobr>print ’Row ’ + str(i) + result</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:20757;left:148"><nobr># Move the database view cursor to next row</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:20775;left:148"><nobr>dbv. next line ()</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:20838;left:108"><nobr>2.4 Persistent Dictionaries</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:20882;left:108"><nobr>A dictionary (hashmap in Java) is a versatile and widely used data structure. Simply put, a dictionary is a</nobr></div>
- <div style="position:absolute;top:20906;left:108"><nobr>set of key/value pairs, supported by a variety of methods for inserting, modifying and accessing the content.</nobr></div>
- <div style="position:absolute;top:20929;left:108"><nobr>In ”plain” Python, the shelve<a href="#1"></a><font style="font-size:8px"><a href="#1">6 </a></font>module offers this functionality. The equivalent in PyS60 is the e32dbm,</nobr></div>
- <div style="position:absolute;top:20952;left:108"><nobr>which, as the name indicates, is built on top of the database module.</nobr></div>
- <div style="position:absolute;top:20988;left:145"><nobr>Note: Only string keys are accepted<a href="#1"></a><font style="font-size:8px"><a href="#1">7</a></font><a href="#1"></a>.</nobr></div>
- <div style="position:absolute;top:21025;left:108"><nobr>Here is a toy implementation with the most important operations.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21055;left:120"><nobr>import e32dbm</nobr></div>
- <div style="position:absolute;top:21073;left:120"><nobr>path = <font color="#4c4c4c"># Your path here</font></nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21092;left:119"><nobr># Construct a full path to your dictionary file</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21110;left:119"><nobr>dname = ” t e s t . d i c t ”</nobr></div>
- <div style="position:absolute;top:21129;left:120"><nobr>dpath = path + dname</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21147;left:119"><nobr># Open the dictionary</nobr></div>
- <div style="position:absolute;top:21166;left:119"><nobr># With the ”c” parameter a new dictionary will be constructed if not there.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21184;left:119"><nobr>d = e32dbm.open(dpath , ”c”)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21203;left:119"><nobr># Add an entry with key ”1” and value ”foo”</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21221;left:119"><nobr>d[”1”] = ”foo”</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21240;left:119"><nobr># Close it</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21258;left:119"><nobr>d. close ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21276;left:119"><nobr># Open i t again , in write mode</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21295;left:119"><nobr>dd = e32dbm.open(dpath , ”w”)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21313;left:119"><nobr># Add a new entry</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21332;left:119"><nobr>dd[”two”] = ”bar”</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:21350;left:119"><nobr>#Iterate over the dictionary</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21368;left:120"><nobr>for key in dd :</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:21397;left:124"><nobr>6<a href="http://docs.python.org/lib/module-shelve.html"></a><font style="font-size:9px"><a href="http://docs.python.org/lib/module-shelve.html">http://docs.python.org/lib/module-shelve.html</a></font></nobr></div>
- <div style="position:absolute;top:21411;left:124"><nobr>7<font style="font-size:9px">CHECK: Listing has strings!</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:21629;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="19"><b>Page 19</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:21745;left:162"><nobr>2.5. Contacts</nobr></div>
- <div style="position:absolute;top:21745;left:795"><nobr>13</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:21816;left:203"><nobr>print key + ’:’ + dd[key]</nobr></div>
- <div style="position:absolute;top:21834;left:173"><nobr>dd . close</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:21893;left:162"><nobr>2.5 Contacts</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:21936;left:162"><nobr>The contacts module lets programmatically access and modify the contact list. The module has one</nobr></div>
- <div style="position:absolute;top:21959;left:162"><nobr>function , open() that returns a ContactDb instance<a href="#1"></a><font style="font-size:8px"><a href="#1">8</a></font></nobr></div>
- <div style="position:absolute;top:21983;left:184"><nobr>The Contact class contains the necessary stuff for dealing with the contact data.</nobr></div>
- <div style="position:absolute;top:22006;left:184"><nobr>Think of the ContactDb as a dictionary of Contact, and db[key] yields a Contact instance.</nobr></div>
- <div style="position:absolute;top:22029;left:184"><nobr>DO A GROUP EXAMPLE!</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:22076;left:177"><nobr>SYMBIAN = True</nobr></div>
- <div style="position:absolute;top:22094;left:175"><nobr>i f</nobr></div>
- <div style="position:absolute;top:22094;left:199"><nobr>SYMBIAN :</nobr></div>
- <div style="position:absolute;top:22113;left:202"><nobr>import e32 , contacts , telephone</nobr></div>
- <div style="position:absolute;top:22131;left:205"><nobr>EMULATOR = e32.in emulator()</nobr></div>
- <div style="position:absolute;top:22168;left:175"><nobr>i f</nobr></div>
- <div style="position:absolute;top:22168;left:199"><nobr>SYMBIAN :</nobr></div>
- <div style="position:absolute;top:22186;left:204"><nobr>i f EMULATOR :</nobr></div>
- <div style="position:absolute;top:22205;left:232"><nobr>path = os.getcwd()</nobr></div>
- <div style="position:absolute;top:22223;left:203"><nobr>else :</nobr></div>
- <div style="position:absolute;top:22242;left:232"><nobr>path = ”E:\\ ”</nobr></div>
- <div style="position:absolute;top:22260;left:175"><nobr>else :</nobr></div>
- <div style="position:absolute;top:22279;left:203"><nobr>path = ”C:\\ tmp\\”</nobr></div>
- <div style="position:absolute;top:22334;left:173"><nobr>db = contacts.open()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:22371;left:173"><nobr>#for entry in db:</nobr></div>
- <div style="position:absolute;top:22390;left:173"><nobr>#</nobr></div>
- <div style="position:absolute;top:22390;left:211"><nobr>print db[entry]</nobr></div>
- <div style="position:absolute;top:22427;left:173"><nobr>#contact = db.add contact()</nobr></div>
- <div style="position:absolute;top:22445;left:173"><nobr>#contact.add field(’last name ’, ’jensen ’)</nobr></div>
- <div style="position:absolute;top:22463;left:173"><nobr>#contact . commit ()</nobr></div>
- <div style="position:absolute;top:22500;left:173"><nobr># Here we access the entries as Contact objects</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:22519;left:174"><nobr>for entry in db :</nobr></div>
- <div style="position:absolute;top:22537;left:203"><nobr>cont = db[entry]</nobr></div>
- <div style="position:absolute;top:22555;left:203"><nobr>print ’ . . . . . . . . . . . . . . cont : ’ + s t r ( cont )</nobr></div>
- <div style="position:absolute;top:22574;left:203"><nobr>print ’ . . . . . . . . . . . . . . cont . id : ’ + s t r ( cont . id )</nobr></div>
- <div style="position:absolute;top:22611;left:174"><nobr>c1 =</nobr></div>
- <div style="position:absolute;top:22611;left:216"><nobr>db . find ( ’ jensen ’ )</nobr></div>
- <div style="position:absolute;top:22629;left:174"><nobr>print ’jensen:’ + str(c1[0].id)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:22673;left:178"><nobr>8<font style="font-size:9px">Custom contact databases may be created by providing a file argument, but only for testing purposes!</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:22891;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="20"><b>Page 20</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:23007;left:108"><nobr>14</nobr></div>
- <div style="position:absolute;top:23007;left:613"><nobr>Chapter 2. Storing Stuff</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:23096;left:119"><nobr>#print db. field types ()</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:23157;left:108"><nobr>2.6 Calendar</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:23200;left:108"><nobr>TBD.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:23254;left:108"><nobr>2.7 Phone Logs</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:23297;left:108"><nobr>Your mobile device keeps track of a lot of events, in various logs. From version 1.4.2, PyS60 , provides an</nobr></div>
- <div style="position:absolute;top:23321;left:108"><nobr>interface to these logs with the logs module. Curently the following types of logs are supported: call, sms,</nobr></div>
- <div style="position:absolute;top:23344;left:108"><nobr>data, fax, email and scheduler<a href="#1"></a><font style="font-size:8px"><a href="#1">9</a></font><a href="#1"></a>.</nobr></div>
- <div style="position:absolute;top:23367;left:130"><nobr>Let’s find out how many log entries we have on the device. Each log entry is represented as a dictionary,</nobr></div>
- <div style="position:absolute;top:23391;left:108"><nobr>and most of the access functions returns a list of dictionaries:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:23420;left:116"><nobr>>>> import logs</nobr></div>
- <div style="position:absolute;top:23438;left:116"><nobr>>>> all = logs.raw log data()</nobr></div>
- <div style="position:absolute;top:23457;left:116"><nobr>>>> len ( all )</nobr></div>
- <div style="position:absolute;top:23475;left:119"><nobr>4</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:23505;left:108"><nobr>We want to print every item in the dictionary representing the log entry. If the key is ”time”, we convert it to</nobr></div>
- <div style="position:absolute;top:23529;left:108"><nobr>readable data, otherwise print it as raw strings:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:23558;left:116"><nobr>>>> import time</nobr></div>
- <div style="position:absolute;top:23576;left:116"><nobr>>>> for key in entry :</nobr></div>
- <div style="position:absolute;top:23595;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:23595;left:178"><nobr>i f key == ’time’:</nobr></div>
- <div style="position:absolute;top:23613;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:23613;left:235"><nobr>value = time.localtime(entry[key])</nobr></div>
- <div style="position:absolute;top:23632;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:23632;left:178"><nobr>else :</nobr></div>
- <div style="position:absolute;top:23650;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:23650;left:235"><nobr>value = entry[key]</nobr></div>
- <div style="position:absolute;top:23669;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:23669;left:178"><nobr>str(key) + ” : ” + str(value)</nobr></div>
- <div style="position:absolute;top:23687;left:122"><nobr>...</nobr></div>
- <div style="position:absolute;top:23705;left:121"><nobr>’ status : Delivered ’</nobr></div>
- <div style="position:absolute;top:23724;left:121"><nobr>’direction : Incoming’</nobr></div>
- <div style="position:absolute;top:23742;left:121"><nobr>’description : Short message’</nobr></div>
- <div style="position:absolute;top:23761;left:121"><nobr>’duration type : −1’</nobr></div>
- <div style="position:absolute;top:23779;left:121"><nobr>’ number : +4792462429 ’</nobr></div>
- <div style="position:absolute;top:23798;left:121"><nobr>’contact : −1’</nobr></div>
- <div style="position:absolute;top:23816;left:121"><nobr>’flags : 2’</nobr></div>
- <div style="position:absolute;top:23835;left:121"><nobr>’time : (2008, 2, 16, 18, 17, 55, 5, 47, −1) ’</nobr></div>
- <div style="position:absolute;top:23853;left:121"><nobr>’duration : 0’</nobr></div>
- <div style="position:absolute;top:23872;left:121"><nobr>’link : 0’</nobr></div>
- <div style="position:absolute;top:23890;left:121"><nobr>’ s u b j e c t : Klem ’</nobr></div>
- <div style="position:absolute;top:23909;left:121"><nobr>’data : \x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:23935;left:124"><nobr>9<font style="font-size:9px">What the heck is scheduler? No google clues...</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:24153;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="21"><b>Page 21</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:24269;left:162"><nobr>2.8. Inbox</nobr></div>
- <div style="position:absolute;top:24269;left:795"><nobr>15</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:24339;left:173"><nobr>\x00\x00\x01\x00\x00\x00 ’</nobr></div>
- <div style="position:absolute;top:24358;left:175"><nobr>’id : 86’</nobr></div>
- <div style="position:absolute;top:24377;left:175"><nobr>’name : ’</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:24437;left:162"><nobr>2.8 Inbox</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:24481;left:162"><nobr>The inbox module offers access to device inbox, outbox, sent and drafts folders. Currently, only the incom-</nobr></div>
- <div style="position:absolute;top:24504;left:162"><nobr>ing SMS inbox is supported. Let’s have look in the box<a href="#1"></a><font style="font-size:8px"><a href="#1">10</a></font><a href="#1"></a>:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:24533;left:170"><nobr>>>> import inbx , time</nobr></div>
- <div style="position:absolute;top:24552;left:170"><nobr>>>> box = inbox.Inbox()</nobr></div>
- <div style="position:absolute;top:24570;left:170"><nobr>>>> for id in box.sms messages():</nobr></div>
- <div style="position:absolute;top:24589;left:176"><nobr>...</nobr></div>
- <div style="position:absolute;top:24589;left:231"><nobr>”Time: ” + str(time.localtime(box.time(id)))</nobr></div>
- <div style="position:absolute;top:24607;left:176"><nobr>...</nobr></div>
- <div style="position:absolute;top:24607;left:231"><nobr>”Content: ” + box.content(id)</nobr></div>
- <div style="position:absolute;top:24626;left:176"><nobr>...</nobr></div>
- <div style="position:absolute;top:24644;left:175"><nobr>’Time: (2008, 2, 16, 19, 17, 55, 5, 47, −1) ’</nobr></div>
- <div style="position:absolute;top:24663;left:173"><nobr>u’Content: Klem ’</nobr></div>
- <div style="position:absolute;top:24681;left:175"><nobr>’Time: (2008, 2, 16, 19, 10, 20, 5, 47, −1) ’</nobr></div>
- <div style="position:absolute;top:24700;left:173"><nobr>u ’ Content : Klem ’</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:24730;left:184"><nobr>A most interesting feature is the bind function, making it possible to trigger any kind of programmable</nobr></div>
- <div style="position:absolute;top:24753;left:162"><nobr>action when you receive an SMS. Your callback function is executed with the ID of the incoming message as</nobr></div>
- <div style="position:absolute;top:24777;left:162"><nobr>argument, hence you could what you like based on the content and metadata of the message<a href="#1"></a><font style="font-size:8px"><a href="#1">11</a></font><a href="#1"></a>.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:25169;left:174"><nobr>10<font style="font-size:9px">Note that time stamp differs an hour from the data from the log in the previous section, timezones, localtime, summer/wintertime is</font></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:25185;left:162"><nobr>a real hassle, in PyS60 as in other environments...</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:25197;left:174"><nobr>11<font style="font-size:9px">Example to come...</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:25415;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="22"><b>Page 22</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:25712;left:108"><nobr>Chapter 3</nobr></div>
- </span></font>
- <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:25796;left:108"><nobr>Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:25894;left:108"><nobr>In this chapter we deal with GUI important related issues that are not so well documented or examplified. For</nobr></div>
- <div style="position:absolute;top:25918;left:108"><nobr>how to use menus, listboxes, query boxes etc., see existing documentation (Section ??. We will in particular</nobr></div>
- <div style="position:absolute;top:25941;left:108"><nobr>touch upon multithreading, synchronization, background daemons and custom graphical GUIs.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:25994;left:108"><nobr>3.1 Application Patterns</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:26037;left:108"><nobr>The appuifw provides the machinery for building GUI based applications. There is no notion of ”main-</nobr></div>
- <div style="position:absolute;top:26060;left:108"><nobr>loop”, as for instance as in Java. Here we provide you with two application skeletons, one without, on with,</nobr></div>
- <div style="position:absolute;top:26084;left:108"><nobr>a custom main loop.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26111;left:120"><nobr>import e32 , appuifw</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26130;left:119"><nobr># Set application title</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26148;left:120"><nobr>appuifw.app. title = u’No Main Loop App’</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26166;left:119"><nobr># Allocate a text component, which essential is an editor like component</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26185;left:121"><nobr>text = appuifw.Text()</nobr></div>
- <div style="position:absolute;top:26203;left:121"><nobr>text.set(u’Hit Exit when you have seen enough!’)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26222;left:119"><nobr># Acquire an a c t i v e o b j e c t s lock , w i l l be used to keep the GUI a l i v e .</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26240;left:120"><nobr>app lock = e32.Ao lock()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26259;left:119"><nobr># Assign the text component as the application body</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26277;left:120"><nobr>appuifw.app.body = text</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26296;left:119"><nobr># Define what’s going to happen when user hits the Exit button</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26314;left:120"><nobr>def quit ():</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26333;left:148"><nobr># Signal to release the lock , so t h a t the a p p l i c a t i o n can move on</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26351;left:149"><nobr>global app lock</nobr></div>
- <div style="position:absolute;top:26369;left:149"><nobr>app lock . signal ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26388;left:119"><nobr># Assign the quit function to the exit key handler</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26406;left:120"><nobr>appuifw.app.exit key handler = quit</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26425;left:119"><nobr># Wait here until given a signal</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26443;left:120"><nobr>app lock . wait ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26462;left:119"><nobr># Notify that we are gracefully terminating the application</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:26504;left:425"><nobr>16</nobr></div>
- </span></font>
- <div style="position:absolute;top:26677;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="23"><b>Page 23</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:26793;left:162"><nobr>3.2. Active Objects</nobr></div>
- <div style="position:absolute;top:26793;left:795"><nobr>17</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26864;left:174"><nobr>appuifw . note (u ’End! ’ )</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:26893;left:162"><nobr>Here is an example of an explicitly coded main loop:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26922;left:174"><nobr>import e32 , appuifw</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:26941;left:173"><nobr># Set title</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:26959;left:174"><nobr>appuifw.app. title = u’Main Loop App’</nobr></div>
- <div style="position:absolute;top:26978;left:175"><nobr>text = appuifw.Text()</nobr></div>
- <div style="position:absolute;top:26996;left:175"><nobr>text . set (u’ Iteration no: ’)</nobr></div>
- <div style="position:absolute;top:27015;left:174"><nobr>appuifw.app.body = text</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27033;left:173"><nobr># Define exit behavior</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27051;left:174"><nobr>def quit ():</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27070;left:202"><nobr># Set the globally accessible boolean to False</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27088;left:203"><nobr>global run</nobr></div>
- <div style="position:absolute;top:27107;left:203"><nobr>run = False</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27125;left:173"><nobr># Assign the quit function to the key handler</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27144;left:174"><nobr>appuifw.app.exit key handler = quit</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27162;left:173"><nobr># S t a r t main loop , w i l l run as long as run i s True ,</nobr></div>
- <div style="position:absolute;top:27181;left:173"><nobr># t h a t is , u n t i l the e x i t key i s h i t</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27199;left:174"><nobr>run = True</nobr></div>
- <div style="position:absolute;top:27218;left:175"><nobr>i = 1</nobr></div>
- <div style="position:absolute;top:27236;left:174"><nobr>while run :</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27255;left:202"><nobr># Wait for a second</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27273;left:202"><nobr>e32 . ao sleep (1)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27291;left:202"><nobr># Put new text in the UI component</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27310;left:203"><nobr>text . set (u’ Iteration no: ’+str ( i ))</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27328;left:202"><nobr># Update counter</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27347;left:203"><nobr>i += 1</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:27365;left:173"><nobr># Graceful termination</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27384;left:174"><nobr>appuifw . note (u ’End! ’ )</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:27444;left:162"><nobr>3.2 Active Objects</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:27487;left:162"><nobr>TBD</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:27541;left:162"><nobr>3.3 Blocking</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:27584;left:162"><nobr>In this program, longtask may be called several times, causing the several overlapping long tasks</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:27613;left:174"><nobr>import e32 , appuifw</nobr></div>
- <div style="position:absolute;top:27650;left:174"><nobr>def longtask ():</nobr></div>
- <div style="position:absolute;top:27668;left:203"><nobr>timer = e32.Ao timer()</nobr></div>
- <div style="position:absolute;top:27687;left:202"><nobr>max =</nobr></div>
- <div style="position:absolute;top:27687;left:252"><nobr>20</nobr></div>
- <div style="position:absolute;top:27705;left:203"><nobr>i = 0</nobr></div>
- <div style="position:absolute;top:27724;left:203"><nobr>appuifw.note(u’Long task starting ’ ’info’)</nobr></div>
- </span></font>
- <div style="position:absolute;top:27939;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="24"><b>Page 24</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:28055;left:108"><nobr>18</nobr></div>
- <div style="position:absolute;top:28055;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:28126;left:149"><nobr>while i < max :</nobr></div>
- <div style="position:absolute;top:28144;left:178"><nobr>timer . after (1)</nobr></div>
- <div style="position:absolute;top:28163;left:178"><nobr>i += 1</nobr></div>
- <div style="position:absolute;top:28181;left:149"><nobr>timer . cancel ()</nobr></div>
- <div style="position:absolute;top:28200;left:149"><nobr>appuifw . note (u ’Long task finished ’ ’ info ’ )</nobr></div>
- <div style="position:absolute;top:28236;left:121"><nobr>i f</nobr></div>
- <div style="position:absolute;top:28237;left:154"><nobr>name</nobr></div>
- <div style="position:absolute;top:28237;left:205"><nobr>== ’ main</nobr></div>
- <div style="position:absolute;top:28237;left:293"><nobr>’:</nobr></div>
- <div style="position:absolute;top:28273;left:149"><nobr>def quit ():</nobr></div>
- <div style="position:absolute;top:28292;left:178"><nobr>global app lock</nobr></div>
- <div style="position:absolute;top:28310;left:177"><nobr>appuifw . note (u ’ Exit ’ ’ info ’ )</nobr></div>
- <div style="position:absolute;top:28329;left:178"><nobr>app lock . signal ()</nobr></div>
- <div style="position:absolute;top:28366;left:149"><nobr>appuifw.app. title = u’Long Task’</nobr></div>
- <div style="position:absolute;top:28384;left:149"><nobr>appuifw.app.menu = [(u’Long task’, longtask)]</nobr></div>
- <div style="position:absolute;top:28421;left:149"><nobr>appuifw.app.exit key handler = quit</nobr></div>
- <div style="position:absolute;top:28440;left:149"><nobr>app lock = e32.Ao lock()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:28458;left:148"><nobr># Will wait u n t i l a signal i s give , and</nobr></div>
- <div style="position:absolute;top:28458;left:451"><nobr>a l l a c t i v e processes are terminated</nobr></div>
- <div style="position:absolute;top:28477;left:148"><nobr># Without the wait functions , the application would have ended before you</nobr></div>
- <div style="position:absolute;top:28495;left:148"><nobr># had the chance to push the menu button :)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:28513;left:149"><nobr>app lock . wait ()</nobr></div>
- <div style="position:absolute;top:28532;left:149"><nobr>appuifw . note (u ’End! ’ ’ info ’ )</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:28599;left:108"><nobr>3.4 Multitasking</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:28644;left:108"><nobr>TBD: Preemptive vs. cooperating multitasking. Active objects.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:28703;left:108"><nobr>3.5 Daemons</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:28748;left:108"><nobr>A classical application pattern is the daemon concept, i.e., a background process that provides other processes,</nobr></div>
- <div style="position:absolute;top:28771;left:108"><nobr>most often GUI-related, with up-dated information. Obviously, this requires some kind of coordination.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
- <div style="position:absolute;top:28823;left:108"><nobr>3.5.1 Simple daemon</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:28860;left:108"><nobr>Consider a simple toy example, where a daemon just performs heartbeats with a specified interval. It uses a</nobr></div>
- <div style="position:absolute;top:28883;left:108"><nobr>wait function, and for each second, it checks the actual duration using the device clock. It stores the longest</nobr></div>
- <div style="position:absolute;top:28907;left:108"><nobr>duration. We communicate with the daemon by global variables<a href="#1"></a><font style="font-size:8px"><a href="#1">1 </a></font>We also time the beats with the system</nobr></div>
- <div style="position:absolute;top:28930;left:108"><nobr>clock, to possibly detect if the thread is suspended in some way if we for instance run other programs in the</nobr></div>
- <div style="position:absolute;top:28953;left:108"><nobr>foreground.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:28983;left:124"><nobr>1<font style="font-size:9px">Yes, global variables are bad, but in multithreading it sometimes is the best solution.</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:29201;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="25"><b>Page 25</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:29317;left:162"><nobr>3.5. Daemons</nobr></div>
- <div style="position:absolute;top:29317;left:795"><nobr>19</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:29388;left:174"><nobr>import os , time , e32 , thread , appuifw</nobr></div>
- <div style="position:absolute;top:29425;left:174"><nobr>def heartbeat ():</nobr></div>
- <div style="position:absolute;top:29443;left:203"><nobr>global longest</nobr></div>
- <div style="position:absolute;top:29461;left:203"><nobr>global no</nobr></div>
- <div style="position:absolute;top:29480;left:203"><nobr>global beat</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:29499;left:202"><nobr># Use the e32 timer , should be s af e r than time . sleep ( )</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:29517;left:203"><nobr>timer = e32.Ao timer()</nobr></div>
- <div style="position:absolute;top:29535;left:203"><nobr>prev = time.clock()</nobr></div>
- <div style="position:absolute;top:29554;left:203"><nobr>while beat :</nobr></div>
- <div style="position:absolute;top:29572;left:232"><nobr>timer . after (1)</nobr></div>
- <div style="position:absolute;top:29591;left:232"><nobr>curr = time.clock()</nobr></div>
- <div style="position:absolute;top:29609;left:232"><nobr>duration = curr − prev</nobr></div>
- <div style="position:absolute;top:29628;left:232"><nobr>i f duration > longest :</nobr></div>
- <div style="position:absolute;top:29646;left:261"><nobr>longest = duration</nobr></div>
- <div style="position:absolute;top:29665;left:231"><nobr>no += 1</nobr></div>
- <div style="position:absolute;top:29683;left:231"><nobr>prev = curr</nobr></div>
- <div style="position:absolute;top:29702;left:203"><nobr>timer . cancel ()</nobr></div>
- <div style="position:absolute;top:29738;left:175"><nobr>i f</nobr></div>
- <div style="position:absolute;top:29738;left:207"><nobr>name</nobr></div>
- <div style="position:absolute;top:29738;left:259"><nobr>== ’ main</nobr></div>
- <div style="position:absolute;top:29738;left:347"><nobr>’:</nobr></div>
- <div style="position:absolute;top:29757;left:203"><nobr>longest = 0</nobr></div>
- <div style="position:absolute;top:29775;left:202"><nobr>no = 0</nobr></div>
- <div style="position:absolute;top:29794;left:203"><nobr>beat = True</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:29812;left:202"><nobr>#applock = e32.Ao lock()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:29849;left:203"><nobr>def g e t d u r a t i o n ( ) :</nobr></div>
- <div style="position:absolute;top:29867;left:232"><nobr>global longest</nobr></div>
- <div style="position:absolute;top:29886;left:231"><nobr>appuifw . note ( unicode ( longest ) , ’ info ’ )</nobr></div>
- <div style="position:absolute;top:29923;left:203"><nobr>def exit ():</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:29942;left:231"><nobr># Stop the while loop in the daemon</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:29960;left:232"><nobr>global beat</nobr></div>
- <div style="position:absolute;top:29978;left:232"><nobr>beat =</nobr></div>
- <div style="position:absolute;top:29978;left:289"><nobr>False</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:29997;left:231"><nobr># If we have used Alternative 1 (see below),</nobr></div>
- <div style="position:absolute;top:30015;left:231"><nobr># we use the lock to signal that we are finished</nobr></div>
- <div style="position:absolute;top:30034;left:231"><nobr>#global applock</nobr></div>
- <div style="position:absolute;top:30052;left:231"><nobr>#applock . signal ()</nobr></div>
- <div style="position:absolute;top:30071;left:231"><nobr># If we have used Alternative 2 (see below), the wait function automatically</nobr></div>
- <div style="position:absolute;top:30089;left:231"><nobr># detects that the thread is shutting down,</nobr></div>
- <div style="position:absolute;top:30108;left:231"><nobr># and we do not have to signal explicitly</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:30144;left:203"><nobr>appuifw.app. title = u’Heartbeat’</nobr></div>
- <div style="position:absolute;top:30163;left:203"><nobr>appuifw.app.exit key handler = exit</nobr></div>
- <div style="position:absolute;top:30181;left:203"><nobr>appuifw.app.menu = [(u’Beat’, get duration)]</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:30218;left:202"><nobr># p r i n t ’ Daemon − Start ’</nobr></div>
- <div style="position:absolute;top:30237;left:202"><nobr># Spawn the daemon in a separate thread , s to r e the thread id</nobr></div>
- </span></font>
- <div style="position:absolute;top:30463;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="26"><b>Page 26</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:30579;left:108"><nobr>20</nobr></div>
- <div style="position:absolute;top:30579;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:30650;left:150"><nobr>tid = thread.start new thread(heartbeat , ())</nobr></div>
- <div style="position:absolute;top:30668;left:149"><nobr>appuifw.note(u’Thread no ’+str(tid)+’ is now running. ’ ’info’)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:30687;left:148"><nobr># Now, we want the main thread to wait for the daemon to quit before continuing</nobr></div>
- <div style="position:absolute;top:30705;left:148"><nobr># Alternative 1: Use the e32.Ao lock()</nobr></div>
- <div style="position:absolute;top:30724;left:148"><nobr># applock . wait ()</nobr></div>
- <div style="position:absolute;top:30742;left:148"><nobr># Alternative 2: Use the thread id and the PyS60 extension to the</nobr></div>
- <div style="position:absolute;top:30761;left:148"><nobr># thread module: thread.ao waittid(tid)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:30779;left:149"><nobr>thread . ao waittid ( tid )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:30798;left:148"><nobr># Now the daemon is dead, and we continue in the main thread</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:30816;left:149"><nobr>appuifw.note(u’Beats: ’ + str(no) + u’, longest: ’ + str(longest), ’info’)</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:30848;left:130"><nobr>If you play around with this script, run some other applications, maybe browse images in the gallery,</nobr></div>
- <div style="position:absolute;top:30871;left:108"><nobr>make a call...you will notice that the beat intervals may become longer than the sleep time of the timer</nobr></div>
- <div style="position:absolute;top:30894;left:108"><nobr>facility: Why? One reason is that timing stuff is notoriously untrustful, another reason could be that the</nobr></div>
- <div style="position:absolute;top:30918;left:108"><nobr>daemon is suspended while other applications are running<a href="#1"></a><font style="font-size:8px"><a href="#1">2</a></font></nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
- <div style="position:absolute;top:30968;left:108"><nobr>3.5.2 Cooperating threads</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:31004;left:108"><nobr>TBD: EXPLAIN</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:31035;left:120"><nobr>import e32 , appuifw , thread</nobr></div>
- <div style="position:absolute;top:31072;left:120"><nobr>def count ( delta , wait , id ):</nobr></div>
- <div style="position:absolute;top:31090;left:149"><nobr>global run</nobr></div>
- <div style="position:absolute;top:31109;left:149"><nobr>global tasklock</nobr></div>
- <div style="position:absolute;top:31127;left:149"><nobr>global i</nobr></div>
- <div style="position:absolute;top:31146;left:149"><nobr>global no</nobr></div>
- <div style="position:absolute;top:31164;left:149"><nobr>global curr id</nobr></div>
- <div style="position:absolute;top:31201;left:149"><nobr>timer = e32.Ao timer()</nobr></div>
- <div style="position:absolute;top:31220;left:149"><nobr>rounds = 5</nobr></div>
- <div style="position:absolute;top:31256;left:149"><nobr>while run :</nobr></div>
- <div style="position:absolute;top:31275;left:178"><nobr>tasklock . acquire ()</nobr></div>
- <div style="position:absolute;top:31293;left:178"><nobr>r = 0</nobr></div>
- <div style="position:absolute;top:31312;left:177"><nobr>while run and r < rounds :</nobr></div>
- <div style="position:absolute;top:31330;left:206"><nobr>timer . after ( wait )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:31349;left:205"><nobr>#tasklock . acquire ()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:31367;left:207"><nobr>curr id = id</nobr></div>
- <div style="position:absolute;top:31386;left:207"><nobr>i += delta</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:31404;left:205"><nobr>#tasklock . release ()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:31423;left:206"><nobr>no = r+1</nobr></div>
- <div style="position:absolute;top:31441;left:206"><nobr>r += 1</nobr></div>
- <div style="position:absolute;top:31460;left:178"><nobr>tasklock . release ()</nobr></div>
- <div style="position:absolute;top:31478;left:149"><nobr>timer . cancel ()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:31507;left:124"><nobr>2<font style="font-size:9px">Any more explanations, anybody?</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:31725;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="27"><b>Page 27</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:31841;left:162"><nobr>3.5. Daemons</nobr></div>
- <div style="position:absolute;top:31841;left:795"><nobr>21</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:31930;left:174"><nobr>def quit ():</nobr></div>
- <div style="position:absolute;top:31949;left:203"><nobr>global run</nobr></div>
- <div style="position:absolute;top:31967;left:203"><nobr>run = False</nobr></div>
- <div style="position:absolute;top:31986;left:203"><nobr>appuifw . note (u ’ Exit ’ )</nobr></div>
- <div style="position:absolute;top:32023;left:174"><nobr>appuifw . app . t i t l e = u ’ Counting Race ’</nobr></div>
- <div style="position:absolute;top:32041;left:175"><nobr>text = appuifw.Text()</nobr></div>
- <div style="position:absolute;top:32059;left:174"><nobr>appuifw.app.body = text</nobr></div>
- <div style="position:absolute;top:32078;left:174"><nobr>appuifw.app.exit key handler = quit</nobr></div>
- <div style="position:absolute;top:32115;left:175"><nobr>tasklock = thread.allocate lock()</nobr></div>
- <div style="position:absolute;top:32152;left:175"><nobr>t i d 1 = thread . s t a r t n e w t h r e a d ( count , (1 ,2 , u ’A’ ) )</nobr></div>
- <div style="position:absolute;top:32170;left:175"><nobr>t i d 2 = thread . s t a r t n e w t h r e a d ( count , (10 ,3 , u ’B’ ) )</nobr></div>
- <div style="position:absolute;top:32207;left:175"><nobr>i = 0</nobr></div>
- <div style="position:absolute;top:32226;left:173"><nobr>no = 1</nobr></div>
- <div style="position:absolute;top:32244;left:174"><nobr>run = True</nobr></div>
- <div style="position:absolute;top:32262;left:175"><nobr>curr id = ’X’</nobr></div>
- <div style="position:absolute;top:32281;left:175"><nobr>t = e32.Ao timer()</nobr></div>
- <div style="position:absolute;top:32299;left:174"><nobr>while run :</nobr></div>
- <div style="position:absolute;top:32318;left:203"><nobr>t . after (0.1)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:32336;left:202"><nobr>#tasklock . acquire ()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:32355;left:203"><nobr>text.set(curr id +u’: Counter: ’ +str(i)+u’, Curr: ’+str(no))</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:32373;left:202"><nobr>#tasklock . release ()</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:32392;left:175"><nobr>t . cancel ()</nobr></div>
- <div style="position:absolute;top:32429;left:174"><nobr>appuifw . note ( u ’The End ’ )</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
- <div style="position:absolute;top:32512;left:162"><nobr>3.5.3 Server threads</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:32555;left:162"><nobr>TBD</nobr></div>
- <div style="position:absolute;top:32582;left:184"><nobr>FROM API:</nobr></div>
- <div style="position:absolute;top:32629;left:199"><nobr>The thread that initializes the Python interpreter becomes the main Python thread. This is usually</nobr></div>
- <div style="position:absolute;top:32653;left:199"><nobr>the main thread of a UI application. When an application written in Python launches, the Sym-</nobr></div>
- <div style="position:absolute;top:32676;left:199"><nobr>bian platform infrastructure creates the main UI thread that starts the Python environment. If a</nobr></div>
- <div style="position:absolute;top:32699;left:199"><nobr>Python program is started as a server with e32.start server, then the Python main thread</nobr></div>
- <div style="position:absolute;top:32723;left:199"><nobr>is not a UI thread.</nobr></div>
- <div style="position:absolute;top:32770;left:162"><nobr>...started by calling the script file.</nobr></div>
- </span></font>
- <div style="position:absolute;top:32987;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="28"><b>Page 28</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:33103;left:108"><nobr>22</nobr></div>
- <div style="position:absolute;top:33103;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
- <div style="position:absolute;top:33170;left:108"><nobr>3.5.4 Threads and GUI</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:33209;left:108"><nobr>The main lesson in this chapter is the following</nobr></div>
- <div style="position:absolute;top:33251;left:145"><nobr>DO NOT USE thread FUNCTIONS IN THE MAIN UI (appuifw) THREAD!</nobr></div>
- <div style="position:absolute;top:33293;left:108"><nobr>When trying to coordinate GUI operations, for instance keep the GUI alive without a main loop, use the</nobr></div>
- <div style="position:absolute;top:33317;left:108"><nobr>Ao lock machinery. Using thread module functionality would most certainly harm the application, per-</nobr></div>
- <div style="position:absolute;top:33340;left:108"><nobr>haps make it hang.</nobr></div>
- <div style="position:absolute;top:33365;left:130"><nobr>This is an example on WHAT YOU SHOULD NOT DO:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:33399;left:120"><nobr>import e32 , appuifw , thread</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:33418;left:119"><nobr># Define a task that takes about 10 seconds</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:33436;left:120"><nobr>def longtask ():</nobr></div>
- <div style="position:absolute;top:33454;left:149"><nobr>global tasklock</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:33473;left:148"><nobr># Get a lock to make sure that only one longtask can run</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:33492;left:149"><nobr>tasklock . acquire ()</nobr></div>
- <div style="position:absolute;top:33510;left:149"><nobr>timer = e32.Ao timer()</nobr></div>
- <div style="position:absolute;top:33528;left:148"><nobr>max =</nobr></div>
- <div style="position:absolute;top:33528;left:198"><nobr>10</nobr></div>
- <div style="position:absolute;top:33547;left:149"><nobr>i = 0</nobr></div>
- <div style="position:absolute;top:33565;left:149"><nobr>appuifw.note(u’Long task starting ’ ’info’)</nobr></div>
- <div style="position:absolute;top:33584;left:149"><nobr>while i < max :</nobr></div>
- <div style="position:absolute;top:33602;left:178"><nobr>timer . after (1)</nobr></div>
- <div style="position:absolute;top:33621;left:178"><nobr>i += 1</nobr></div>
- <div style="position:absolute;top:33639;left:149"><nobr>timer . cancel ()</nobr></div>
- <div style="position:absolute;top:33658;left:149"><nobr>appuifw . note (u ’Long task finished ’ ’ info ’ )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:33676;left:148"><nobr># Task is finished</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:33695;left:149"><nobr>tasklock . release ()</nobr></div>
- <div style="position:absolute;top:33731;left:120"><nobr>def quit ():</nobr></div>
- <div style="position:absolute;top:33750;left:149"><nobr>global app lock</nobr></div>
- <div style="position:absolute;top:33768;left:149"><nobr>appuifw . note (u ’ Exit ’ ’ info ’ )</nobr></div>
- <div style="position:absolute;top:33787;left:149"><nobr>app lock . signal ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:33824;left:119"><nobr># Allocate the global lock</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:33842;left:121"><nobr>tasklock = thread.allocate lock()</nobr></div>
- <div style="position:absolute;top:33861;left:120"><nobr>appuifw.app. title = u’Erroneous App’</nobr></div>
- <div style="position:absolute;top:33879;left:120"><nobr>appuifw.app.menu = [(u’Long task’, longtask)]</nobr></div>
- <div style="position:absolute;top:33898;left:120"><nobr>appuifw.app.exit key handler = quit</nobr></div>
- <div style="position:absolute;top:33916;left:120"><nobr>app lock = e32.Ao lock()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:33935;left:119"><nobr># Will wait u n t i l a signal i s give , and</nobr></div>
- <div style="position:absolute;top:33935;left:415"><nobr>a l l</nobr></div>
- <div style="position:absolute;top:33935;left:451"><nobr>a c t i v e processes are terminated</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:33953;left:120"><nobr>app lock . wait ()</nobr></div>
- <div style="position:absolute;top:33971;left:120"><nobr>appuifw . note (u ’End! ’ ’ info ’ )</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:34008;left:130"><nobr>If you press ”Long task” once, and wait until it finish, everything is OK. Press it a second, before the first</nobr></div>
- <div style="position:absolute;top:34032;left:108"><nobr>task is complete, then you app hangs.</nobr></div>
- </span></font>
- <div style="position:absolute;top:34249;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="29"><b>Page 29</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:34365;left:162"><nobr>3.6. Graphics</nobr></div>
- <div style="position:absolute;top:34365;left:795"><nobr>23</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:34429;left:162"><nobr>3.6 Graphics</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:34474;left:162"><nobr>PyS60 does not offer high level functionality for developing advanced graphic user interfaces for use in for</nobr></div>
- <div style="position:absolute;top:34498;left:162"><nobr>instance game applications. Basically, you have to draw everything on a canvas, with simple operations</nobr></div>
- <div style="position:absolute;top:34521;left:162"><nobr>as draw lines, circles, rectangles, text etc., and implement custom callback functions for various feedback,</nobr></div>
- <div style="position:absolute;top:34544;left:162"><nobr>typically from keyboard events.</nobr></div>
- <div style="position:absolute;top:34568;left:184"><nobr>To illustrate the basic concepts of low level graphics user interface programming, we will through an</nobr></div>
- <div style="position:absolute;top:34592;left:162"><nobr>implementation of the classical battleship game<a href="#1"></a><font style="font-size:8px"><a href="#1">3 </a></font>In this game, you guess where ships are located in an area,</nobr></div>
- <div style="position:absolute;top:34615;left:162"><nobr>drop a bomb at the guessed location, and either you will hit (a part of) a ship and get notified, or you miss,</nobr></div>
- <div style="position:absolute;top:34638;left:162"><nobr>and get notified. The goal is to minimize the number of bombs to sink all the ships.</nobr></div>
- <div style="position:absolute;top:34662;left:184"><nobr>In our implementation<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>, a random ship is generated, and the user may move around in the “ocean” with</nobr></div>
- <div style="position:absolute;top:34686;left:162"><nobr>the navigation keys, and press hit at a guessed location. If there is a ship, an explosion sound will be heard,</nobr></div>
- <div style="position:absolute;top:34709;left:162"><nobr>and a fire image is displayed. Otherwise, the system will do nothing but display an image of an empty ocean.</nobr></div>
- <div style="position:absolute;top:34732;left:162"><nobr>When all parts of the ship are hit, a score will be displayed. The user interface is based on a grid layout, see</nobr></div>
- <div style="position:absolute;top:34756;left:162"><nobr>Figure <a href="#29">3.1.</a></nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
- <div style="position:absolute;top:35113;left:411"><nobr>Figure 3.1: Battleship game</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:35154;left:184"><nobr>The first part of the implementation is a utility function for making transparent images. After that comes</nobr></div>
- <div style="position:absolute;top:35178;left:162"><nobr>global definitions of colors, files, etc. Then we implement the game logic in a separate class, BattleShip,</nobr></div>
- <div style="position:absolute;top:35201;left:162"><nobr>and finally we implement the main user interface thread.</nobr></div>
- <div style="position:absolute;top:35225;left:184"><nobr>When doing graphics manipulations, you will soon feel the need for pasting transparent image pieces</nobr></div>
- <div style="position:absolute;top:35248;left:162"><nobr>on top of the canvas. Transparency is not supported on PyS60 , however, the copy function, blit, allows</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:35279;left:178"><nobr>3<font style="font-size:9px">Add a GPS, a map, then you can extend the battleship concept to a fun “mixed reality” application, see e.g., “Battleship by foot”[<a href="#44">1]</a>.</font></nobr></div>
- <div style="position:absolute;top:35293;left:178"><nobr>4<font style="font-size:9px">The implementation is bare-bone, with a minimal amount of security nets and optimized code.</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:35511;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="30"><b>Page 30</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:35627;left:108"><nobr>24</nobr></div>
- <div style="position:absolute;top:35627;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- <div style="position:absolute;top:35696;left:108"><nobr>you to specify a black-and-white mask, which will copy only the pixels in the white part of the mask, hence,</nobr></div>
- <div style="position:absolute;top:35719;left:108"><nobr>simulating transparency. To accomplish this, we implement a handy automask function, that takes an image</nobr></div>
- <div style="position:absolute;top:35742;left:108"><nobr>and produces a corresponding black-and-white image mask, where we assume the transparency color is found</nobr></div>
- <div style="position:absolute;top:35766;left:108"><nobr>in the upper left corner<a href="#1"></a><font style="font-size:8px"><a href="#1">5</a></font><a href="#1"></a>:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:35794;left:120"><nobr>import appuifw , e32 , key codes , graphics , random , os , audio</nobr></div>
- <div style="position:absolute;top:35830;left:120"><nobr>def automask(im):</nobr></div>
- <div style="position:absolute;top:35849;left:149"><nobr>width , height = im . s i z e</nobr></div>
- <div style="position:absolute;top:35867;left:148"><nobr>mask = graphics.Image.new(im.size , ’1’) <font color="#4c4c4c"># black and white</font></nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:35886;left:119"><nobr># Undocumented getpixel function :)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:35904;left:149"><nobr>tran = im.getpixel((0, 0))[0]</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:35905;left:377"><nobr># transparent upper−left</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:35923;left:149"><nobr>for y in range ( height ):</nobr></div>
- <div style="position:absolute;top:35941;left:178"><nobr>l i n e = im . g e t p i x e l ( [ ( x , y ) for x in range ( width ) ] )</nobr></div>
- <div style="position:absolute;top:35960;left:178"><nobr>for x in range ( width ):</nobr></div>
- <div style="position:absolute;top:35978;left:207"><nobr>i f line[x] == tran:</nobr></div>
- <div style="position:absolute;top:35997;left:234"><nobr>mask . point (( x , y ) , 0)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:35997;left:392"><nobr># mask on the point</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:36015;left:149"><nobr>return mask</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:36044;left:108"><nobr>Then we define global constants for colors, files etc.:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:36072;left:118"><nobr>WHITE = (255,255,255)</nobr></div>
- <div style="position:absolute;top:36090;left:118"><nobr>RED = (255,0,0)</nobr></div>
- <div style="position:absolute;top:36109;left:118"><nobr>BLUE = (0,0,255)</nobr></div>
- <div style="position:absolute;top:36127;left:118"><nobr>YELLOW = (255,255,0)</nobr></div>
- <div style="position:absolute;top:36146;left:118"><nobr>BLACK = (0, 0, 0)</nobr></div>
- <div style="position:absolute;top:36164;left:118"><nobr>GRAY = (200, 200, 200)</nobr></div>
- <div style="position:absolute;top:36201;left:118"><nobr>COVER = BLACK</nobr></div>
- <div style="position:absolute;top:36220;left:118"><nobr>SEA = BLUE</nobr></div>
- <div style="position:absolute;top:36238;left:118"><nobr>CURSOR = YELLOW</nobr></div>
- <div style="position:absolute;top:36256;left:117"><nobr>BACKGROUND = BLACK</nobr></div>
- <div style="position:absolute;top:36275;left:118"><nobr>BLAST = RED</nobr></div>
- <div style="position:absolute;top:36293;left:118"><nobr>MESSAGE BG = GRAY</nobr></div>
- <div style="position:absolute;top:36312;left:118"><nobr>MESSAGE FG = BLACK</nobr></div>
- <div style="position:absolute;top:36349;left:118"><nobr>CURSOR OUTLINE WIDTH = 1</nobr></div>
- <div style="position:absolute;top:36386;left:118"><nobr>PATH = u’C:\\ Data\\Images\\ ’</nobr></div>
- <div style="position:absolute;top:36404;left:119"><nobr>SEAFILE = PATH+u’sea1.png’</nobr></div>
- <div style="position:absolute;top:36423;left:119"><nobr>BLASTFILE = PATH+u’exp00.png’</nobr></div>
- <div style="position:absolute;top:36441;left:118"><nobr>BANGFILE = PATH+u’bang1.wav’</nobr></div>
- <div style="position:absolute;top:36478;left:120"><nobr>SHIP SIZE = 3</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:36507;left:108"><nobr>We use a separate class to encapsulate the game logic. It uses an image self.ui to implement the graphics</nobr></div>
- <div style="position:absolute;top:36530;left:108"><nobr>actions. The image is copied to the canvas element of the appuifw framework when the redraw function</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:36555;left:124"><nobr>5<font style="font-size:9px">Thanks to Korakot Chaovavan<a href="http://snippets.dzone.com/tag/blit">ich, http://snippets.dzone.com/tag/blit.</a></font></nobr></div>
- </span></font>
- <div style="position:absolute;top:36773;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="31"><b>Page 31</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:36889;left:162"><nobr>3.6. Graphics</nobr></div>
- <div style="position:absolute;top:36889;left:795"><nobr>25</nobr></div>
- <div style="position:absolute;top:36958;left:162"><nobr>is called. The class is also taking care of the keyboard events. The first part is initializing the datastructures</nobr></div>
- <div style="position:absolute;top:36981;left:162"><nobr>and variables:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37007;left:175"><nobr>class BattleShip :</nobr></div>
- <div style="position:absolute;top:37026;left:175"><nobr>’ ’ ’dx , dy : size of each grid cell in pixels .</nobr></div>
- <div style="position:absolute;top:37044;left:175"><nobr>ui size : size of canvas</nobr></div>
- <div style="position:absolute;top:37063;left:172"><nobr>OBS: We assume the the grid size is divisible width the ui size</nobr></div>
- <div style="position:absolute;top:37081;left:175"><nobr>’’’</nobr></div>
- <div style="position:absolute;top:37100;left:203"><nobr>def</nobr></div>
- <div style="position:absolute;top:37100;left:247"><nobr>i n i t</nobr></div>
- <div style="position:absolute;top:37100;left:289"><nobr>( self , dx , dy , u i s i z e ) :</nobr></div>
- <div style="position:absolute;top:37118;left:232"><nobr>self.dx = dx</nobr></div>
- <div style="position:absolute;top:37137;left:232"><nobr>self.dy = dy</nobr></div>
- <div style="position:absolute;top:37155;left:232"><nobr>s e l f .m = u i s i z e [ 0 ] / s e l f . dx</nobr></div>
- <div style="position:absolute;top:37174;left:232"><nobr>s e l f . n = u i s i z e [ 1 ] / s e l f . dy</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:37192;left:231"><nobr># Define top row as message pane</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37211;left:232"><nobr>self.message rect = (0, 0, self.dx∗ self .m, 1∗ self .dy)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:37229;left:231"><nobr># Define start point for message text</nobr></div>
- <div style="position:absolute;top:37248;left:231"><nobr># TBD: This is a bit tricky , can be automated.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37266;left:232"><nobr>self.message pos = (5, self.dy−1)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:37285;left:231"><nobr># Keep track bombs used</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37303;left:232"><nobr>self.bombs = 0</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:37321;left:231"><nobr># Remember if we have completed sinking the boat</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37340;left:232"><nobr>self.finished = False</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:37358;left:231"><nobr># Vertical or horizontal ship</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37377;left:232"><nobr>r = random.randint(0,1)</nobr></div>
- <div style="position:absolute;top:37395;left:232"><nobr>i f r == 0:</nobr></div>
- <div style="position:absolute;top:37414;left:261"><nobr>self.ship vertical = True</nobr></div>
- <div style="position:absolute;top:37432;left:232"><nobr>else :</nobr></div>
- <div style="position:absolute;top:37451;left:261"><nobr>self.ship vertical = False</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:37469;left:231"><nobr># Randomly position the ship on the canvas (not in the message area :)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:37487;left:232"><nobr>self.shiplocations = []</nobr></div>
- <div style="position:absolute;top:37506;left:232"><nobr>i f self . ship vertical :</nobr></div>
- <div style="position:absolute;top:37524;left:261"><nobr>i = random.randint(0, self.m−1)</nobr></div>
- <div style="position:absolute;top:37543;left:259"><nobr>x = i ∗ self .dx</nobr></div>
- <div style="position:absolute;top:37561;left:261"><nobr>j = y = random.randint(1, self.n−SHIP SIZE )</nobr></div>
- <div style="position:absolute;top:37580;left:259"><nobr>y = j ∗ self .dy</nobr></div>
- <div style="position:absolute;top:37598;left:260"><nobr>for tmp in range(SHIP SIZE):</nobr></div>
- <div style="position:absolute;top:37635;left:290"><nobr>self . shiplocations . append ((x, y))</nobr></div>
- <div style="position:absolute;top:37654;left:288"><nobr>y += self.dy</nobr></div>
- <div style="position:absolute;top:37672;left:289"><nobr>j += 1</nobr></div>
- <div style="position:absolute;top:37690;left:232"><nobr>else :</nobr></div>
- <div style="position:absolute;top:37709;left:261"><nobr>i = random.randint(0, self.m−SHIP SIZE )</nobr></div>
- <div style="position:absolute;top:37727;left:259"><nobr>x = i ∗ self .dx</nobr></div>
- <div style="position:absolute;top:37746;left:261"><nobr>j = random.randint(0, self.n−1)</nobr></div>
- <div style="position:absolute;top:37764;left:259"><nobr>y = j ∗ self .dy</nobr></div>
- <div style="position:absolute;top:37783;left:260"><nobr>for tmp in range(SHIP SIZE):</nobr></div>
- <div style="position:absolute;top:37801;left:290"><nobr>self . shiplocations . append ((x, y))</nobr></div>
- <div style="position:absolute;top:37820;left:288"><nobr>x += self.dx</nobr></div>
- </span></font>
- <div style="position:absolute;top:38035;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="32"><b>Page 32</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:38151;left:108"><nobr>26</nobr></div>
- <div style="position:absolute;top:38151;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38222;left:235"><nobr>i += 1</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38240;left:177"><nobr># For recording hits:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38259;left:178"><nobr>self.hitlocations = []</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38277;left:177"><nobr># Random start position</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38296;left:178"><nobr>i = random.randint(0, self.m−1)</nobr></div>
- <div style="position:absolute;top:38314;left:178"><nobr>j = random.randint(1, self.n−1)</nobr></div>
- <div style="position:absolute;top:38333;left:178"><nobr>self.curr pos = (i ∗ self .dx , j ∗ self .dy)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38351;left:177"><nobr># Need to keep track of both current and next position</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38369;left:178"><nobr>self.next pos = ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38388;left:177"><nobr># Initialize the ui image used for double buffering ,</nobr></div>
- <div style="position:absolute;top:38406;left:177"><nobr># set ui to cover the ship locations and the sea</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38425;left:178"><nobr>self.ui = graphics.Image.new(ui size)</nobr></div>
- <div style="position:absolute;top:38443;left:178"><nobr>s e l f . u i . c l e a r (COVER)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38462;left:177"><nobr># Generate the sea image, equal size as canvas</nobr></div>
- <div style="position:absolute;top:38480;left:177"><nobr># If the seafile is not there , use a SEA colored background</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38498;left:178"><nobr>try :</nobr></div>
- <div style="position:absolute;top:38517;left:207"><nobr>self.sea = graphics.Image.open(SEAFILE)</nobr></div>
- <div style="position:absolute;top:38535;left:178"><nobr>except :</nobr></div>
- <div style="position:absolute;top:38554;left:207"><nobr>self.sea = graphics.Image.new(self.ui.size)</nobr></div>
- <div style="position:absolute;top:38572;left:207"><nobr>self . sea . clear (SEA)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38591;left:177"><nobr># Generate the blast image, equal size as the grid cells</nobr></div>
- <div style="position:absolute;top:38609;left:177"><nobr># If the blastfile is not there , use a BLAST colored cell</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38628;left:178"><nobr>try :</nobr></div>
- <div style="position:absolute;top:38646;left:207"><nobr>blast = graphics.Image.open(BLASTFILE)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38665;left:205"><nobr># Make mask for simulating transparency</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38683;left:206"><nobr>blastmask = automask(blast)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38702;left:205"><nobr># Make mask for simulating transparency</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38720;left:207"><nobr>self.blast = blast.resize((self.dx, self.dy))</nobr></div>
- <div style="position:absolute;top:38739;left:207"><nobr>self.blastmask = blastmask.resize((self.dx, self.dy))</nobr></div>
- <div style="position:absolute;top:38757;left:178"><nobr>except :</nobr></div>
- <div style="position:absolute;top:38775;left:207"><nobr>self.blast = graphics.Image.new((self.dx, self.dy))</nobr></div>
- <div style="position:absolute;top:38794;left:207"><nobr>self . blast . clear (BLAST)</nobr></div>
- <div style="position:absolute;top:38812;left:207"><nobr>self.blastmask = None</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38831;left:177"><nobr># Open BANG file , no fallback :(</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38849;left:178"><nobr>self.bang = audio.Sound.open(BANGFILE)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38868;left:177"><nobr># Initialize an image to remember the erased part of the canvas</nobr></div>
- <div style="position:absolute;top:38886;left:177"><nobr># Will be used when moving around and dropping bombs</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38905;left:178"><nobr>self.erased cell = graphics.Image.new((self.dx, self.dy))</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38923;left:177"><nobr># Start with copying current cell from the ui image</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38942;left:178"><nobr>self . erased cell . blit ( self .ui , source=self . curr pos)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:38960;left:177"><nobr># Draw cursor rectangle at current position</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:38978;left:177"><nobr>pos = (self.curr pos[0], self.curr pos[1], \</nobr></div>
- <div style="position:absolute;top:38997;left:229"><nobr>self . curr pos [0]+ self .dx, self . curr pos [1]+ self .dy)</nobr></div>
- <div style="position:absolute;top:39015;left:178"><nobr>self . ui . rectangle (pos , outline = CURSOR, width = CURSOR OUTLINE WIDTH)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39034;left:177"><nobr># Draw welcome message</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39052;left:178"><nobr>self .drawmessage(u’VELKOMMEN TIL SJ SLAG ’ , RED)</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:39080;left:108"><nobr>Then, define utility functions and callback prodedures:</nobr></div>
- </span></font>
- <div style="position:absolute;top:39297;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="33"><b>Page 33</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:39413;left:162"><nobr>3.6. Graphics</nobr></div>
- <div style="position:absolute;top:39413;left:795"><nobr>27</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39484;left:203"><nobr>def drawmessage( self , message , col ):</nobr></div>
- <div style="position:absolute;top:39502;left:203"><nobr>’ ’ ’Draw message r e c t a n g e l with color col , the draw message t e x t ’ ’ ’</nobr></div>
- <div style="position:absolute;top:39521;left:232"><nobr>self.ui.rectangle(self.message rect , fill = col)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39539;left:231"><nobr># print message</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39558;left:232"><nobr>self . ui . text ( self . message pos , message)</nobr></div>
- <div style="position:absolute;top:39594;left:203"><nobr>def move( self , pos ):</nobr></div>
- <div style="position:absolute;top:39613;left:203"><nobr>’’’Move from current position to position pos’’’</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39632;left:231"><nobr># Copy the erased cell back to canvas (cover our traces)</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39650;left:232"><nobr>self . ui . blit ( self . erased cell , target=self . curr pos)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39668;left:231"><nobr># Update next position</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39687;left:232"><nobr>self.next pos = pos</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39705;left:231"><nobr># Store content of next cell in erased cell</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39724;left:232"><nobr>self . erased cell . blit ( self .ui , source=self . next pos)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39742;left:231"><nobr># Paint cursor rectangle in next position</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39761;left:232"><nobr>rect = (self.next pos[0], self.next pos[1], \</nobr></div>
- <div style="position:absolute;top:39779;left:290"><nobr>self . next pos[0]+ self .dx, self . next pos[1]+ self .dy)</nobr></div>
- <div style="position:absolute;top:39798;left:232"><nobr>self . ui . rectangle ( rect , outline = CURSOR, width = CURSOR OUTLINE WIDTH)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39816;left:231"><nobr># Prepare for next move</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39834;left:232"><nobr>self.curr pos = self.next pos</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39871;left:202"><nobr># Define nvaigation functions to be used in key event callbacks</nobr></div>
- <div style="position:absolute;top:39890;left:202"><nobr># We implement wrap−around navigation , going over the top brings us to the bottom etc .</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39927;left:203"><nobr>def up( self ):</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:39945;left:202"><nobr># Do note move into messagepane</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:39963;left:232"><nobr>i f self.curr pos[1] == 1∗ self .dy:</nobr></div>
- <div style="position:absolute;top:39982;left:259"><nobr>y = (self.n−1)∗ self .dy</nobr></div>
- <div style="position:absolute;top:40000;left:232"><nobr>else :</nobr></div>
- <div style="position:absolute;top:40019;left:259"><nobr>y = self.curr pos[1]− self .dy</nobr></div>
- <div style="position:absolute;top:40037;left:231"><nobr>new pos = (self.curr pos[0], y)</nobr></div>
- <div style="position:absolute;top:40056;left:232"><nobr>self .move(new pos)</nobr></div>
- <div style="position:absolute;top:40093;left:203"><nobr>def down( self ):</nobr></div>
- <div style="position:absolute;top:40111;left:232"><nobr>i f self.curr pos[1] == (self.n−1)∗ self .dy:</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:40130;left:231"><nobr># Do note move into messagepane</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:40148;left:259"><nobr>y = 1∗ self .dy</nobr></div>
- <div style="position:absolute;top:40166;left:232"><nobr>else :</nobr></div>
- <div style="position:absolute;top:40185;left:259"><nobr>y = self.curr pos[1]+self.dy</nobr></div>
- <div style="position:absolute;top:40204;left:231"><nobr>new pos = (self.curr pos[0], y)</nobr></div>
- <div style="position:absolute;top:40222;left:232"><nobr>self .move(new pos)</nobr></div>
- <div style="position:absolute;top:40259;left:203"><nobr>def left ( self ):</nobr></div>
- <div style="position:absolute;top:40277;left:232"><nobr>i f self.curr pos[0] == 0:</nobr></div>
- <div style="position:absolute;top:40296;left:259"><nobr>x = (self.m−1)∗ self .dx</nobr></div>
- <div style="position:absolute;top:40314;left:232"><nobr>else :</nobr></div>
- <div style="position:absolute;top:40333;left:259"><nobr>x = self.curr pos[0]− self .dx</nobr></div>
- </span></font>
- <div style="position:absolute;top:40559;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="34"><b>Page 34</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:40675;left:108"><nobr>28</nobr></div>
- <div style="position:absolute;top:40675;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:40746;left:177"><nobr>new pos = (x, self.curr pos[1])</nobr></div>
- <div style="position:absolute;top:40764;left:178"><nobr>self .move(new pos)</nobr></div>
- <div style="position:absolute;top:40801;left:149"><nobr>def right ( self ):</nobr></div>
- <div style="position:absolute;top:40819;left:178"><nobr>i f self.curr pos[0] == (self.m−1)∗ self .dx:</nobr></div>
- <div style="position:absolute;top:40838;left:205"><nobr>x = 0</nobr></div>
- <div style="position:absolute;top:40856;left:178"><nobr>else :</nobr></div>
- <div style="position:absolute;top:40875;left:205"><nobr>x = self.curr pos[0]+self.dx</nobr></div>
- <div style="position:absolute;top:40893;left:177"><nobr>new pos = (x, self.curr pos[1])</nobr></div>
- <div style="position:absolute;top:40912;left:178"><nobr>self .move(new pos)</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:40946;left:108"><nobr>Further, we implement beahviour for hitting the “fire button”:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:40978;left:149"><nobr>def hit ( self ):</nobr></div>
- <div style="position:absolute;top:40997;left:178"><nobr>self.bombs += 1</nobr></div>
- <div style="position:absolute;top:41015;left:178"><nobr>cell pos = (self.curr pos[0], self.curr pos[1], self.curr pos[0]+self.dx,\</nobr></div>
- <div style="position:absolute;top:41033;left:257"><nobr>self . curr pos [1]+ self .dy)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41052;left:177"><nobr># Ship hit?</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41070;left:178"><nobr>i f self.curr pos in self . shiplocations :</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41089;left:205"><nobr># First copy the sea background to the cell</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41107;left:207"><nobr>self . ui . blit ( self .sea , target=cell pos , source=cell pos )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41126;left:205"><nobr># Then, copy the ”transparent” blast image</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41144;left:207"><nobr>self . ui . blit ( self . blast , target=cell pos , mask=self . blastmask)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41163;left:205"><nobr># Play bang sound : Must check i f i t ’ s s t i l l playing sound of previous h i t .</nobr></div>
- <div style="position:absolute;top:41181;left:205"><nobr># If so , stop it .</nobr></div>
- <div style="position:absolute;top:41200;left:205"><nobr># Remember : Only one speaker , t r y i n g to do overlapping replays r a i s e s error</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41218;left:207"><nobr>i f self.bang.state() == audio.EPlaying:</nobr></div>
- <div style="position:absolute;top:41237;left:236"><nobr>self . bang . stop ()</nobr></div>
- <div style="position:absolute;top:41255;left:207"><nobr>self . bang . play ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41274;left:205"><nobr># Mark hit by removing the location , and append to hit locations list</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41292;left:207"><nobr>self . shiplocations .remove( self . curr pos )</nobr></div>
- <div style="position:absolute;top:41310;left:207"><nobr>self . hitlocations .append( self . curr pos )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41329;left:205"><nobr># Update message pan</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41347;left:207"><nobr>s e l f . drawmessage ( u ’ Antall bomber : ’+unicode ( s e l f . bombs)+u ’ , \</nobr></div>
- <div style="position:absolute;top:41366;left:236"><nobr>antall treff : ’+unicode(len( self . hitlocations )) , GRAY)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41384;left:205"><nobr># Are we done?</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41402;left:207"><nobr>i f len(self.shiplocations) == 0:</nobr></div>
- <div style="position:absolute;top:41421;left:236"><nobr>if not self . finished :</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41440;left:263"><nobr># Compute score and update message pane</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41458;left:264"><nobr>score = ((SHIP SIZE ∗ 1.0)/( self .bombs ∗ 1.0)) ∗ 100.0</nobr></div>
- <div style="position:absolute;top:41476;left:264"><nobr>self . drawmessage (u ’ Gratulerer ! Score : ’+unicode ( score )+ ’%’ , GRAY)</nobr></div>
- <div style="position:absolute;top:41495;left:264"><nobr>self.finished = True</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41513;left:177"><nobr># CHECK : U n n e s c e s s a r y ?</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41532;left:179"><nobr>elif self.curr pos in self . hitlocations :</nobr></div>
- <div style="position:absolute;top:41550;left:207"><nobr>self . ui . blit ( self . blast , target=cell pos )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:41569;left:177"><nobr># If no hit ,just paint the sea</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:41587;left:178"><nobr>else :</nobr></div>
- <div style="position:absolute;top:41606;left:207"><nobr>self . ui . blit ( self .sea , target=cell pos , source=cell pos )</nobr></div>
- </span></font>
- <div style="position:absolute;top:41821;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="35"><b>Page 35</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:41937;left:162"><nobr>3.6. Graphics</nobr></div>
- <div style="position:absolute;top:41937;left:795"><nobr>29</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:42026;left:231"><nobr># Remember the current content , and repaint the cursor rectangle ,</nobr></div>
- <div style="position:absolute;top:42045;left:231"><nobr># then we are ready for next move</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:42063;left:232"><nobr>self . erased cell . blit ( self .ui , source=self . curr pos)</nobr></div>
- <div style="position:absolute;top:42082;left:232"><nobr>rect = (self.next pos[0], self.next pos[1], \</nobr></div>
- <div style="position:absolute;top:42100;left:290"><nobr>self . next pos[0]+ self .dx, self . next pos[1]+ self .dy)</nobr></div>
- <div style="position:absolute;top:42119;left:232"><nobr>self . ui . rectangle ( rect , outline = CURSOR, width = CURSOR OUTLINE WIDTH)</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:42148;left:162"><nobr>Now the Battleship class is ready, and we continue with implementing the application. We start with the</nobr></div>
- <div style="position:absolute;top:42171;left:162"><nobr>callback functions.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:42200;left:174"><nobr>def handle redraw(rect ):</nobr></div>
- <div style="position:absolute;top:42219;left:175"><nobr>’ ’ ’ Callback for the appuifw canvas object .</nobr></div>
- <div style="position:absolute;top:42237;left:174"><nobr>Will be used each time the canvas needs to be updated’’’</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:42256;left:202"><nobr># Could be called before the canvas image has been i n i t i a l i z e d .</nobr></div>
- <div style="position:absolute;top:42274;left:202"><nobr># Otherwise , just copy ui to the canvas object</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:42292;left:204"><nobr>i f ui :</nobr></div>
- <div style="position:absolute;top:42311;left:231"><nobr>canvas . blit ( ui )</nobr></div>
- <div style="position:absolute;top:42348;left:174"><nobr>def handle event(event):</nobr></div>
- <div style="position:absolute;top:42366;left:175"><nobr>’ ’ ’ Callback for the appuifw canvas object : Handles key events ’ ’ ’</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:42385;left:202"><nobr># Could be called before the b a t t l e s h i p object has been i n i t i a l i z e d .</nobr></div>
- <div style="position:absolute;top:42403;left:202"><nobr># Otherwise , bind key events to the navigation f u n c t i o n s in b a t t l e s h i p</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:42422;left:204"><nobr>if not battleship :</nobr></div>
- <div style="position:absolute;top:42440;left:231"><nobr>return</nobr></div>
- <div style="position:absolute;top:42459;left:202"><nobr>ev = event[’keycode’]</nobr></div>
- <div style="position:absolute;top:42477;left:204"><nobr>i f ev == key codes.EKeyUpArrow:</nobr></div>
- <div style="position:absolute;top:42495;left:232"><nobr>battleship .up()</nobr></div>
- <div style="position:absolute;top:42514;left:204"><nobr>elif ev == key codes.EKeyRightArrow:</nobr></div>
- <div style="position:absolute;top:42532;left:232"><nobr>battleship . right ()</nobr></div>
- <div style="position:absolute;top:42551;left:204"><nobr>elif ev == key codes.EKeyDownArrow:</nobr></div>
- <div style="position:absolute;top:42569;left:232"><nobr>b a t t l e s h i p . down ( )</nobr></div>
- <div style="position:absolute;top:42588;left:204"><nobr>elif ev == key codes.EKeyLeftArrow:</nobr></div>
- <div style="position:absolute;top:42606;left:232"><nobr>battleship . left ()</nobr></div>
- <div style="position:absolute;top:42625;left:204"><nobr>elif ev == key codes.EKeySelect:</nobr></div>
- <div style="position:absolute;top:42643;left:232"><nobr>battleship . hit ()</nobr></div>
- <div style="position:absolute;top:42662;left:203"><nobr>handle redraw(None)</nobr></div>
- <div style="position:absolute;top:42698;left:174"><nobr>def quit ():</nobr></div>
- <div style="position:absolute;top:42717;left:175"><nobr>’’’To be assigned the exit key handler , closes sound file and gives signal</nobr></div>
- <div style="position:absolute;top:42735;left:204"><nobr>if battleship :</nobr></div>
- <div style="position:absolute;top:42754;left:232"><nobr>battleship . bang . close ()</nobr></div>
- <div style="position:absolute;top:42772;left:203"><nobr>app lock . signal ()</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:42802;left:162"><nobr>The last thing to do is to kick off the application framework:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:42831;left:174"><nobr>ui = None</nobr></div>
- <div style="position:absolute;top:42849;left:175"><nobr>battleship = None</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:42868;left:173"><nobr># Initialize canvas and bind callback functions</nobr></div>
- </span></font>
- <div style="position:absolute;top:43083;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="36"><b>Page 36</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:43199;left:108"><nobr>30</nobr></div>
- <div style="position:absolute;top:43199;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43270;left:120"><nobr>canvas = appuifw.Canvas(\</nobr></div>
- <div style="position:absolute;top:43288;left:250"><nobr>redraw callback = handle redraw ,\</nobr></div>
- <div style="position:absolute;top:43307;left:250"><nobr>event callback = handle event)</nobr></div>
- <div style="position:absolute;top:43325;left:120"><nobr>appuifw.app.body = canvas</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43344;left:119"><nobr># We want a full screen app</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43362;left:120"><nobr>appuifw . app . screen = ’ f u l l ’</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43381;left:119"><nobr># Bind the quit function</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43399;left:120"><nobr>appuifw.app.exit key handler = quit</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43418;left:119"><nobr># CHECK!</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43436;left:120"><nobr>handle redraw(None)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43454;left:119"><nobr># Initialize the game logic class</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43473;left:121"><nobr>battleship = BattleShip(20, 20, canvas.size)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43491;left:119"><nobr># Make the ui image accessible to the application thread</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43510;left:120"><nobr>ui = battleship.ui</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43528;left:119"><nobr># CHECK!</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43547;left:120"><nobr>handle redraw(None)</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43565;left:119"><nobr># Wait for the shut down signal</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:43584;left:120"><nobr>app lock = e32.Ao lock()</nobr></div>
- <div style="position:absolute;top:43602;left:120"><nobr>app lock . wait ()</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:43621;left:119"><nobr>#That ’s it !</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:43651;left:130"><nobr>So, play away!</nobr></div>
- </span></font>
- <div style="position:absolute;top:44345;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="37"><b>Page 37</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:44643;left:162"><nobr>Chapter 4</nobr></div>
- </span></font>
- <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:44728;left:162"><nobr>Networking</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:44828;left:162"><nobr>TBD: HTTP, client server</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:44887;left:162"><nobr>4.1 Bluetooth</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:44933;left:162"><nobr>Most (all?) S60 devices may communicate by bluetooth, a short range (typically ¡ 10m) wireless protocol</nobr></div>
- <div style="position:absolute;top:44956;left:162"><nobr>The PyS60 API offers a dedicated socket implementation. Typically, bluetooth devices advert their services,</nobr></div>
- <div style="position:absolute;top:44980;left:162"><nobr>and other devices must discover such devices, and then connect to them, optionally using a shared passkey</nobr></div>
- <div style="position:absolute;top:45003;left:162"><nobr>the devices agree upon. The discovery and connection process implemented in PyS60 requires the user to</nobr></div>
- <div style="position:absolute;top:45026;left:162"><nobr>manually search, select and connect to a device. If you want this process to run silently in the background</nobr></div>
- <div style="position:absolute;top:45050;left:162"><nobr>with no user interaction, you need to use the native API and build your own extension<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>.</nobr></div>
- <div style="position:absolute;top:45074;left:184"><nobr>The bluetooth mechanics are well documented in the standard PyS60 sources, see Section <a href="#42">6.</a></nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
- <div style="position:absolute;top:45127;left:162"><nobr>4.1.1 External GPS</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:45165;left:162"><nobr>Communication with an external GPS device (over bluetooth) involves parsing the NMEA formatted ASCII</nobr></div>
- <div style="position:absolute;top:45188;left:162"><nobr>stream from the GPS. NMEA 0183 is a standard from the US based National Marine Electronics Associa-</nobr></div>
- <div style="position:absolute;top:45211;left:162"><nobr>tion. You may download<a href="#1"></a><font style="font-size:8px"><a href="#1">2 </a></font>it for USD 270, or rely on a reversed engineered version, for instance from Dale</nobr></div>
- <div style="position:absolute;top:45235;left:162"><nobr>DePriest<a href="#1"></a><font style="font-size:8px"><a href="#1">3</a></font><a href="#1"></a>, which is the source for the following information.</nobr></div>
- <div style="position:absolute;top:45259;left:184"><nobr>An NMEA device is transmitting a stream of NMEA sentences, all starting with a dollar sign and two</nobr></div>
- <div style="position:absolute;top:45282;left:162"><nobr>characters identifying the “talker”, which in the GPS case is “$GP”. Each sentence is terminated with a</nobr></div>
- <div style="position:absolute;top:45306;left:162"><nobr>checksum starting with “*” and followed by two hex digits. The checksum represents an 8 bit exclusive OR</nobr></div>
- <div style="position:absolute;top:45329;left:162"><nobr>of all characters between, but not including, the “$” and “*”. The tokens of the sentences are separated by</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:45360;left:178"><nobr>1<font style="font-size:9px">Check<a href="http://www.mobilenin.com/pys60/info_bluetooth.htm"> http://www.mobilenin.com/pys60/info_bluetooth.htm if you need</a> non-interactive bluetooth functionality</font></nobr></div>
- <div style="position:absolute;top:45375;left:178"><nobr>2<a href="http://www.nmea.org/pub/0183/"></a><font style="font-size:9px"><a href="http://www.nmea.org/pub/0183/">http://www.nmea.org/pub/0183/</a></font></nobr></div>
- <div style="position:absolute;top:45389;left:178"><nobr>3<a href="http://www.gpsinformation.org/dale/nmea.htm"></a><font style="font-size:9px"><a href="http://www.gpsinformation.org/dale/nmea.htm">http://www.gpsinformation.org/dale/nmea.htm</a></font></nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:45434;left:478"><nobr>31</nobr></div>
- </span></font>
- <div style="position:absolute;top:45607;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="38"><b>Page 38</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:45723;left:108"><nobr>32</nobr></div>
- <div style="position:absolute;top:45723;left:619"><nobr>Chapter 4. Networking</nobr></div>
- <div style="position:absolute;top:45792;left:108"><nobr>commas<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>. A typical NMEA sentence may looks like this:</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
- <div style="position:absolute;top:45832;left:168"><nobr>$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:45868;left:108"><nobr>However:</nobr></div>
- <div style="position:absolute;top:45906;left:168"><nobr>There is no way to indicate anything back to the unit as to whether the sentence is being</nobr></div>
- <div style="position:absolute;top:45929;left:145"><nobr>read correctly or to request a re-send of some data you didn’t get. Instead the receiving unit just</nobr></div>
- <div style="position:absolute;top:45953;left:145"><nobr>checks the checksum and ignores the data if the checksum is bad figuring the data will be sent</nobr></div>
- <div style="position:absolute;top:45976;left:145"><nobr>again sometime later.</nobr></div>
- <div style="position:absolute;top:46014;left:108"><nobr>Each sentence type is identify by three letters following directly after the prefix, in the case above, “RMC”,</nobr></div>
- <div style="position:absolute;top:46037;left:108"><nobr>standing for “Recommended Minimum sentence C”. Hence, a useful parsing algorithm is as follows:</nobr></div>
- <div style="position:absolute;top:46060;left:130"><nobr>• Read one line (terminated by CR/LF) at the time</nobr></div>
- <div style="position:absolute;top:46083;left:130"><nobr>• If the sentence starts with “$GP” and ends with a checksum:</nobr></div>
- <div style="position:absolute;top:46108;left:163"><nobr>– Compute and verify the checksum, and if it’s OK:</nobr></div>
- <div style="position:absolute;top:46130;left:191"><nobr>∗ Identify the sentence type</nobr></div>
- <div style="position:absolute;top:46153;left:191"><nobr>∗ Extract and interpret the tokens according to the NMEA specification</nobr></div>
- <div style="position:absolute;top:46178;left:130"><nobr>Let’s check what sentences our GPS<a href="#1"></a><font style="font-size:8px"><a href="#1">5 </a></font>produces:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:46209;left:120"><nobr>import socket</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:46246;left:119"><nobr># Find a bluetooth GPS</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:46265;left:120"><nobr>address , s e r v i c e s = socket . b t d i s c o v e r ( )</nobr></div>
- <div style="position:absolute;top:46283;left:120"><nobr>print ”Discovered: %s, %s” % (address , services)</nobr></div>
- <div style="position:absolute;top:46302;left:121"><nobr>t a r g e t = ( address , s e r v i c e s . values ( ) [ 0 ] )</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:46339;left:119"><nobr>#Connect</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:46357;left:120"><nobr>conn = socket . socket ( socket .AF BT, socket .SOCK STREAM)</nobr></div>
- <div style="position:absolute;top:46376;left:120"><nobr>conn . connect ( target )</nobr></div>
- <div style="position:absolute;top:46394;left:120"><nobr>gps = conn.makefile(”r”, 0)</nobr></div>
- <div style="position:absolute;top:46431;left:120"><nobr>while True :</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:46449;left:148"><nobr># Get sentence , strip of CR/NL or other whitespace</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:46468;left:149"><nobr>sentence = gps . r e a d l i n e ( ) . s t r i p ( )</nobr></div>
- <div style="position:absolute;top:46486;left:150"><nobr>i f sentence[0:3] == ’$GP’ and sentence[−3] == ’∗ ’ :</nobr></div>
- <div style="position:absolute;top:46505;left:178"><nobr>print sentence [3:6]</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:46537;left:130"><nobr>Our device speaks the following sentences: RMC: Recommended Minimum sentence C, GGA: Global</nobr></div>
- <div style="position:absolute;top:46561;left:108"><nobr>Positioning System Fix Data, GSV: Satellites in view, GSA: Satellite status, and VTG: Track made good and</nobr></div>
- <div style="position:absolute;top:46584;left:108"><nobr>ground speed.</nobr></div>
- <div style="position:absolute;top:46608;left:130"><nobr>RMC is one of the most used sentences, and is structured as follows:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:46637;left:124"><nobr>4<font style="font-size:9px">Note that prefix “$GP” and the checksum suffix are not comma separated</font></nobr></div>
- <div style="position:absolute;top:46651;left:124"><nobr>5<font style="font-size:9px">In this case a HOLUX GPSlim 240</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:46869;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="39"><b>Page 39</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:46985;left:162"><nobr>4.1. Bluetooth</nobr></div>
- <div style="position:absolute;top:46985;left:795"><nobr>33</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:47056;left:207"><nobr>RMC</nobr></div>
- <div style="position:absolute;top:47056;left:302"><nobr>Recommended Minimum sentence C</nobr></div>
- <div style="position:absolute;top:47074;left:209"><nobr>123519</nobr></div>
- <div style="position:absolute;top:47074;left:303"><nobr>Fix taken at 12:35:19 UTC</nobr></div>
- <div style="position:absolute;top:47093;left:208"><nobr>A</nobr></div>
- <div style="position:absolute;top:47093;left:304"><nobr>Status A=active or V=Void .</nobr></div>
- <div style="position:absolute;top:47111;left:210"><nobr>4807.038,N</nobr></div>
- <div style="position:absolute;top:47111;left:304"><nobr>Latitude 48 deg 07.038’ N</nobr></div>
- <div style="position:absolute;top:47130;left:210"><nobr>01131.000,E</nobr></div>
- <div style="position:absolute;top:47130;left:303"><nobr>Longitude 11 deg 31.000’ E</nobr></div>
- <div style="position:absolute;top:47148;left:210"><nobr>022.4</nobr></div>
- <div style="position:absolute;top:47148;left:303"><nobr>Speed over the ground in knots</nobr></div>
- <div style="position:absolute;top:47167;left:210"><nobr>084.4</nobr></div>
- <div style="position:absolute;top:47167;left:303"><nobr>Track angle in degrees True</nobr></div>
- <div style="position:absolute;top:47185;left:209"><nobr>230394</nobr></div>
- <div style="position:absolute;top:47185;left:303"><nobr>Date − 23rd of March 1994</nobr></div>
- <div style="position:absolute;top:47203;left:210"><nobr>003.1 ,W</nobr></div>
- <div style="position:absolute;top:47203;left:303"><nobr>Magnetic Variation</nobr></div>
- <div style="position:absolute;top:47221;left:209"><nobr>∗6A</nobr></div>
- <div style="position:absolute;top:47222;left:302"><nobr>The checksum data , always begins with ∗</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:47252;left:162"><nobr>For instance, the latitude is the fourth token, and the longitude is the sixth:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:47282;left:174"><nobr>def parse RMC sentence(sentence body):</nobr></div>
- <div style="position:absolute;top:47301;left:203"><nobr>tokens = sentence body . s p l i t ( ” , ” )</nobr></div>
- <div style="position:absolute;top:47319;left:204"><nobr>lat= tokens[3]</nobr></div>
- <div style="position:absolute;top:47338;left:203"><nobr>lon = tokens[5]</nobr></div>
- <div style="position:absolute;top:47356;left:202"><nobr>e w = tokens[6]</nobr></div>
- <div style="position:absolute;top:47374;left:203"><nobr>return [lat , lon]</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:47405;left:162"><nobr>Note that the geographic coordinates are a bit oddly formatted, the most common format (in digital applica-</nobr></div>
- <div style="position:absolute;top:47428;left:162"><nobr>tions), is decimal degrees. The following snippet will do the trick:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:47458;left:174"><nobr>def format latlong dec(coord):</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:47477;left:202"><nobr># Based on nmea info.py v0.27,</nobr></div>
- <div style="position:absolute;top:47477;left:432"><nobr>Nick Burch (03/12/2007)</nobr></div>
- <div style="position:absolute;top:47495;left:202"><nobr># Turn DDMM.nnnn into DD.ddddd</nobr></div>
- <div style="position:absolute;top:47514;left:202"><nobr># 1 degree = 60 minutes</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:47550;left:204"><nobr>i f coord[5:6] == ’.’:</nobr></div>
- <div style="position:absolute;top:47569;left:232"><nobr>degrees = float(coord[0:3])</nobr></div>
- <div style="position:absolute;top:47587;left:232"><nobr>minutes = float(coord[3:])</nobr></div>
- <div style="position:absolute;top:47606;left:204"><nobr>elif coord[3:4] == ’.’:</nobr></div>
- <div style="position:absolute;top:47624;left:232"><nobr>degrees = float(coord[0:1])</nobr></div>
- <div style="position:absolute;top:47643;left:232"><nobr>minutes = float(coord[1:])</nobr></div>
- <div style="position:absolute;top:47661;left:203"><nobr>else :</nobr></div>
- <div style="position:absolute;top:47680;left:232"><nobr>degrees = float(coord[0:2])</nobr></div>
- <div style="position:absolute;top:47698;left:232"><nobr>minutes = float(coord[2:])</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:47717;left:202"><nobr># Minutes must be converted to decimal fraction of a degree</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:47735;left:203"><nobr>decimals = minutes / 60.0</nobr></div>
- <div style="position:absolute;top:47753;left:203"><nobr>return degrees + decimals</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:47784;left:162"><nobr>This works OK in the N/E global quadrant. If you are below equator or west of the Greenwich meridian, use</nobr></div>
- <div style="position:absolute;top:47807;left:162"><nobr>the additional N/S and E/W information to set the proper sign on the coordinate values. And here is how to</nobr></div>
- <div style="position:absolute;top:47831;left:162"><nobr>compute the checksum if you want to make your app as robust as possible:</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:47860;left:174"><nobr>def generate checksum(data):</nobr></div>
- <div style="position:absolute;top:47879;left:231"><nobr>”””Generate the NMEA checksum for the supplied data”””</nobr></div>
- <div style="position:absolute;top:47897;left:231"><nobr>”””From Nick Burch − nmea info.py v0.27 (03/12/2007) ”””</nobr></div>
- </span></font>
- <div style="position:absolute;top:48131;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="40"><b>Page 40</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:48247;left:108"><nobr>34</nobr></div>
- <div style="position:absolute;top:48247;left:619"><nobr>Chapter 4. Networking</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:48318;left:177"><nobr>csum = 0</nobr></div>
- <div style="position:absolute;top:48336;left:178"><nobr>for c in data :</nobr></div>
- <div style="position:absolute;top:48355;left:234"><nobr>csum = csum ˆ ord(c)</nobr></div>
- <div style="position:absolute;top:48373;left:177"><nobr>hex csum = ”%02x” % csum</nobr></div>
- <div style="position:absolute;top:48391;left:177"><nobr>return hex csum . upper ()</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:48422;left:108"><nobr>The accuracy of a standard GPS vary quite a bit, but is typically in the range 3-10 meters. You may perhaps</nobr></div>
- <div style="position:absolute;top:48445;left:108"><nobr>want to filter out minor variations, and one way to do this is to update the position only when the distance to</nobr></div>
- <div style="position:absolute;top:48468;left:108"><nobr>the previous position is larger than a given threshold. Since the geographic grid is highly non-uniform, you</nobr></div>
- <div style="position:absolute;top:48492;left:108"><nobr>need a special formulae to compute these distances<a href="#1"></a><font style="font-size:8px"><a href="#1">6</a></font></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:48521;left:120"><nobr>import math</nobr></div>
- </span></font>
- <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
- <div style="position:absolute;top:48558;left:119"><nobr># radians and degrees are omitted from the pys60 math distribution</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:48576;left:120"><nobr>def radians ( degrees ):</nobr></div>
- <div style="position:absolute;top:48595;left:149"><nobr>return ( math . pi ∗ degrees ) / 180.0</nobr></div>
- <div style="position:absolute;top:48632;left:120"><nobr>def distance ( lat1 , lon1 , lat2 , lon2 ):</nobr></div>
- <div style="position:absolute;top:48650;left:177"><nobr>”””Computes the geodesic distance , in meters ,</nobr></div>
- <div style="position:absolute;top:48669;left:177"><nobr>between two locations expressed in geographic coordinates</nobr></div>
- <div style="position:absolute;top:48687;left:177"><nobr>Ref : http : / / en . wikipedia . org / wiki / Haversine formula”””</nobr></div>
- <div style="position:absolute;top:48724;left:176"><nobr>R = 6371000 <font color="#4c4c4c"># Earth radius in meters ( approximately )</font></nobr></div>
- <div style="position:absolute;top:48761;left:177"><nobr>dLat = radians(float(lat2)− float ( lat1 ))</nobr></div>
- <div style="position:absolute;top:48780;left:177"><nobr>dLon = radians(float(lon2)− float ( lon1 ))</nobr></div>
- <div style="position:absolute;top:48798;left:177"><nobr>a = math.sin(dLat/2.0) ∗ math . sin ( dLat /2.0) \</nobr></div>
- <div style="position:absolute;top:48817;left:176"><nobr>+ math . cos ( radians ( f l o a t ( l a t 1 ) ) ) ∗ math . cos ( radians ( float ( lat2 ))) \</nobr></div>
- <div style="position:absolute;top:48834;left:176"><nobr>∗ math . s i n ( dLon / 2 . 0 ) ∗ math . s i n ( dLon / 2 . 0 ) ;</nobr></div>
- <div style="position:absolute;top:48853;left:177"><nobr>c = 2.0 ∗ math . atan2 ( math . sqrt ( a ) , math . sqrt (1.0 − a))</nobr></div>
- <div style="position:absolute;top:48872;left:177"><nobr>return R ∗ c</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:49175;left:124"><nobr>6<font style="font-size:9px">Yeah, this is a bit overkill, many approximative approaches can be used in stead...</font></nobr></div>
- </span></font>
- <div style="position:absolute;top:49393;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="41"><b>Page 41</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:49690;left:162"><nobr>Chapter 5</nobr></div>
- </span></font>
- <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:49774;left:162"><nobr>Various</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:49879;left:162"><nobr>5.1 Debugging</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:49923;left:162"><nobr>When running a GUI application, exceptions, warnings and error messages might be directed to the stdout</nobr></div>
- <div style="position:absolute;top:49946;left:162"><nobr>pipe<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>. The GUI can act strangely, but not go down, thus it might be hard to figure out what’s going on. When</nobr></div>
- <div style="position:absolute;top:49969;left:162"><nobr>exiting the application, some clues can be found among messages written to the python ”console”. Log files</nobr></div>
- <div style="position:absolute;top:49993;left:162"><nobr>should be used: EXAMPLE TBD.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:50437;left:178"><nobr>1<font style="font-size:9px">CHECK!</font></nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:50482;left:478"><nobr>35</nobr></div>
- </span></font>
- <div style="position:absolute;top:50655;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="42"><b>Page 42</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
- <div style="position:absolute;top:50953;left:108"><nobr>Chapter 6</nobr></div>
- </span></font>
- <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:51037;left:108"><nobr>Resources</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:51144;left:108"><nobr>6.1 Python</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:51189;left:108"><nobr>A classic Python starter is “Dive Into Python” [<a href="#44">2]</a>, which is available on a variety of formats. The father</nobr></div>
- <div style="position:absolute;top:51212;left:108"><nobr>of Python, Guido van Rossum, has (of course) wriiten a good intro book[4<a href="#44">],</a> “Introduction to Python”, also</nobr></div>
- <div style="position:absolute;top:51235;left:108"><nobr>available online. Documentation of modules, classes, functions etc. is <a href="http://docs.python.org">found on http://docs.python.</a></nobr></div>
- <div style="position:absolute;top:51259;left:108"><nobr><a href="http://docs.python.org">org.</a></nobr></div>
- <div style="position:absolute;top:51283;left:130"><nobr>You can access to the Python source code on python.org. If you want to extend the PyS60 distribution</nobr></div>
- <div style="position:absolute;top:51306;left:108"><nobr>with additional modules, it is best to try the 2.2 version<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>. since this is the one that PyS60 is based on.</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
- <div style="position:absolute;top:51364;left:108"><nobr>6.2 PyS60</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:51409;left:108"><nobr>The main entry for PyS60 information is the proejct’s home page<a href="#1"></a><font style="font-size:8px"><a href="#1">2</a></font><a href="#1"></a>, where you will find links to nescessary</nobr></div>
- <div style="position:absolute;top:51433;left:108"><nobr>software and documentation, for instance “PyS60 Library Reference” for the current version. The 1.2.0</nobr></div>
- <div style="position:absolute;top:51456;left:108"><nobr>release shipped with three useful documents: ”Programming with Python for Series 60” , ”Getting Started</nobr></div>
- <div style="position:absolute;top:51479;left:108"><nobr>with Python for Series 60” and ”API Reference for Python”. Grab them from release bundle or from “Forum</nobr></div>
- <div style="position:absolute;top:51503;left:108"><nobr>Nokia”<a href="#1"></a><font style="font-size:8px"><a href="#1">3 </a></font>while they still are available. The PyS60 section of this forum is a good place to pick up snippets</nobr></div>
- <div style="position:absolute;top:51526;left:108"><nobr>and advices, and also a place where you probably will get answers to your posted questions.</nobr></div>
- <div style="position:absolute;top:51550;left:130"><nobr>Another excellent source is the tutorial from the PyS60 evangelist Jurgen Scheible<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>, including lots of</nobr></div>
- <div style="position:absolute;top:51573;left:108"><nobr>working code examples. He is also the first author of “Mobile Python: Rapid Prototyping of Applications on</nobr></div>
- <div style="position:absolute;top:51597;left:108"><nobr>the Mobile Platform”[<a href="#44">3]</a>. You can dowload all the example code from the book web site<font style="font-size:8px"><a href="#1">5</a></font></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:51627;left:124"><nobr>1<font style="font-size:9px">http://python.org/download/releases/2.2.3</font></nobr></div>
- <div style="position:absolute;top:51641;left:124"><nobr>2<a href="http://wiki.opensource.nokia.com/projects/PyS60"></a><font style="font-size:9px"><a href="http://wiki.opensource.nokia.com/projects/PyS60">http://wiki.opensource.nokia.com/projects/PyS60</a></font></nobr></div>
- <div style="position:absolute;top:51656;left:124"><nobr>3<a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html"></a><font style="font-size:9px"><a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html">http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/</a></font></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
- <div style="position:absolute;top:51673;left:108"><nobr><a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html">Python_for_S60.html</a></nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:51685;left:124"><nobr>4<a href="http://www.mobilenin.com/pys60/menu.htm"></a><font style="font-size:9px"><a href="http://www.mobilenin.com/pys60/menu.htm">http://www.mobilenin.com/pys60/menu.htm</a></font></nobr></div>
- <div style="position:absolute;top:51699;left:124"><nobr>5<a href="http://www.mobilepythonbook.org"></a><font style="font-size:9px"><a href="http://www.mobilepythonbook.org">http://www.mobilepythonbook.org</a></font></nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:51744;left:425"><nobr>36</nobr></div>
- </span></font>
- <div style="position:absolute;top:51917;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="43"><b>Page 43</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:52033;left:162"><nobr>6.2. PyS60</nobr></div>
- <div style="position:absolute;top:52033;left:795"><nobr>37</nobr></div>
- <div style="position:absolute;top:52102;left:184"><nobr>There is also good stuff to be find on the blogs from Pankaj Nathani<a href="#1"></a><font style="font-size:8px"><a href="#1">6</a></font><a href="#1"></a>, Nick Burch <font style="font-size:8px"><a href="#1">7 </a></font>and the PyS60</nobr></div>
- <div style="position:absolute;top:52125;left:163"><nobr>über-hacker cyke64<a href="#1"></a><font style="font-size:8px"><a href="#1">8</a></font><a href="#1"></a>.</nobr></div>
- </span></font>
- <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
- <div style="position:absolute;top:52932;left:178"><nobr>6<a href="http://croozeus.googlepages.com/py60"></a><font style="font-size:9px"><a href="http://croozeus.googlepages.com/py60">http://croozeus.googlepages.com/py60</a></font></nobr></div>
- <div style="position:absolute;top:52947;left:178"><nobr>7<a href="http://gagravarr.org/code"></a><font style="font-size:9px"><a href="http://gagravarr.org/code">http://gagravarr.org/code</a></font></nobr></div>
- <div style="position:absolute;top:52961;left:178"><nobr>8<a href="http://cyke64.googlepages.com"></a><font style="font-size:9px"><a href="http://cyke64.googlepages.com">http://cyke64.googlepages.com</a></font></nobr></div>
- </span></font>
- <div style="position:absolute;top:53179;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="44"><b>Page 44</b></a></font></td></tr></tbody></table></div><font size="5" face="Times"><span style="font-size:35px;font-family:Times">
- <div style="position:absolute;top:53481;left:108"><nobr>Bibliography</nobr></div>
- </span></font>
- <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
- <div style="position:absolute;top:53580;left:108"><nobr>[1] Nicola J Bidwell and Jason Holdsworth. Battleship by foot: learning by designing a mixed reality game.</nobr></div>
- <div style="position:absolute;top:53603;left:133"><nobr>In IE ’06: Procedings of the 3rd Australasian conference on Interactive entertainment, pages 67–74,</nobr></div>
- <div style="position:absolute;top:53626;left:133"><nobr>Murdoch University, Australia, Australia, 2006. Murdoch University.</nobr></div>
- <div style="position:absolute;top:53662;left:108"><nobr>[2] M. Pilgrim. Dive Into Python. Apress,<a href="http://www.diveintopython.org"> 2004. http://www.diveintopython.org.</a></nobr></div>
- <div style="position:absolute;top:53697;left:108"><nobr>[3] J. Scheible and V. Tuulos. Mobile Python-Rapid Prototyping on the Mobile Platform, 2007.</nobr></div>
- <div style="position:absolute;top:53732;left:108"><nobr>[4] G. Van Rossum.</nobr></div>
- <div style="position:absolute;top:53732;left:267"><nobr>Introduction to Python.</nobr></div>
- <div style="position:absolute;top:53732;left:444"><nobr>Network Theory Ltd., 2006.</nobr></div>
- <div style="position:absolute;top:53733;left:657"><nobr><a href="http://www.network-theory.co.uk/python/intro">http://www.</a></nobr></div>
- <div style="position:absolute;top:53756;left:133"><nobr><a href="http://www.network-theory.co.uk/python/intro">network-theory.co.uk/python/intro.</a></nobr></div>
- <div style="position:absolute;top:54268;left:425"><nobr>38</nobr></div>
- </span></font>
- </div></body></html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement