
Оговорюсь сразу: в этой статье мы будем разбирать пример, работающий на symbian 9.4 (смартфоны с тачскрином), хотя вы без особого труда сможете переделать пример и под более ранние версии symbian. Кроме этого, рассказ будет вестись с учетом работы на windows. Пользователи других операционных систем, без проблем смогут подобрать необходимый софт под свою OS.
Кстати, у программы, которые мы разработаем в этом топике, есть аккаунт в twitter :)
Начнем…
Инструментарий
Выбор инструментов основан на моем личном опыте. Возможно вы пойдете другой дорогой :)
Итак, нам понадобятся:
Установленный на ваш PC python, версии 2.5-2.6. Необходим он для работы утилиты ensymble (о которой будет сказано ниже), для тестирования набросков кода, да и куда уж программисту на питоне без него :)
Далее, скачиваем отсюда «пакет разработчика» для вашей OS. Для windows это будет PythonForS60_1.9.7_Setup.exe. Устанавливаем, и посмотрим что же у нас появилось.
Щелкаем по меню пуск, и находим Python for s60. Там у нас будет утилита ensymble, ссылка на on line документацию (off line доки можно скачать у меня отсюда), ярлык на папку PyS60 Dependencies, которая сейчас нам понадобится.
Открываем папку, и устанавливаем с нее в наш смарт python 1.9.7 (это python runtime, необходимый для работы программ, написанных на питоне, его же и нужно распространять вместе с вашей будущей программой), так же устанавливаем python script shell, который является оболочкой для запуска ваших скриптов непосредственно на смарте (кромер запуска, можно воспользоваться интерактивной консолью питона как со смарта, так и через bluetooth, через hyper terminal например).
Установили?! Теперь остается решить вопрос, в чем писать и как запускать написанное.
Для написания подойдет любой текстовый редактор с поддержкой utf-8, желательно с поддержкой подсветки кода. Какой из сотен редакторов выбрать, решать вам. Ничего особенного от него не требуется, запускать через него мы все равно не будем.
Запускать скрипты можно через эмулятор, но я пользуюсь другим способом, запуская на «живом железе».
У вас наверняка установлена Nokia PC Suite. В этом программе есть «диспетчер файлов», который встраивается в проводник. Но мне, человеку который ненавидим виндовый эксплорер, проще пользоваться замечательным плагином к TotalCommander, который называется NokiaFS (любителм других ФМ, думаю смогут найти в интернете подобные плагины).
Установите соединение между Nokia PC Suite и вашим телефоном. Удобнее всего пользоваться bluetooth, но подойдет и через кабель. Алгоритм прост: набираем код, нажимаем сохранить, переключаемся TC, копируем в телефон скрипт в папку data/python (на том диске, где у вас установлен python и script shell), далее в script shell нажимаем меню и «run script»… У меня руки, привыкшие к шорткатам и функциональным клавишам, делают это за 1-2 секунды :)
Для удобства, из data/python можно удалить примеры, давайте сделаем этот каталог нашей рабочей папкой.
Давайте что нибудь напишем
Напишем мы мега приложение, которое будет заставлять наш телефон мычать, при нажатии на кнопку в центре экрана. И чтобы наше приложение выгодно отличалось от подобных, добавим возможность подсчитывать, сколько раз наш телефон сказал «му» а так же возможность делиться нашими достижениями, добавляя сообщения в твиттер нашей программы twitter.com/pys60_cow :)
Я подразумеваю, что у вас есть хоть какие то знания языка программирования python. Если нет, бегом изучать :) Ссылку на документацию по специфичным для symbian модулям я привел выше.
Напишем «скилет» приложения. Так обычно начинаются мои приложения, в UI которого мы используем Canvas:
- #-*-coding:utf-8-*-
- import sys
- import e32
- from appuifw import *
- from graphics import *
- # app_path - путь, где у нас будут лежать картинки и звуки... app.full_name()[0] это первая буква
- # диска на с которого сейчас работаем
- app_path=app.full_name()[0]+u':\\data\\python\\'
- # путь, где будет лежать файл с числом нажатий, позже этот путь мы изменим
- data_path=app_path
- class Main:
- def __init__(self):
- # оключаем экранную клавиатуру
- app.directional_pad=False
- # открываем джепегешку с фоновой картинкой
- self.splash=Image.open(app_path+'splash.jpg')
- # инициализируем холст, на котором будем в дальнейшем работать
- # в redraw_callback указываем функцию, которая будет вызывать при перерисовке экрана.
- self.canvas=Canvas(redraw_callback=self.redraw)
- # указываем, что виден на экране у нас будет canvas
- app.body=self.canvas
- def redraw(self,rect):
- # помещаем на canvas нашу картинку
- self.canvas.blit(self.splash)
- # создаем объект lock, который нужен, чтоб ваше приложение не закрылось сразу после открытия
- lock=e32.Ao_lock()
- # при нажатии правую софт клавишу, освобождаем lock, приложение закроется.
- app.exit_key_handler=lock.signal
- a=Main()
- lock.wait()
Обязательно рисуем картинку к программе. Я не художник, для теста пока сгодится вот эта моя поделка.

Теперь осталось оживить наш нашу программу, добавив возможность нашей корове мычать. Открываем картинку в редакторе и линейкой меряем, где у нас находится картинка.
Добавляем в __init__ следующие строки:
# забиндим на координаты, где у нас иконка коровы функцию say_mu
self.canvas.bind(EButton1Down,self.say_mu,((44,171),(300,400)))
# открываем звук мычания коровы
self.mu=audio.Sound.open(app_path+'cow.mp3')
Теперь напишем функцию say_mu. Хочу обратить внимание, что функции сообщается, тьюпл, который содержит в себе координаты, куда мы ткнули пальцем, но они нам пока не нужны. И наконец пишем функцию, которая будет «мычать»
def say_mu(self,event):
# если звук уже играет, останавливаем его
if self.mu.state()==audio.EPlaying:
self.mu.stop()
self.mu.play()
Не забываем закинуть файл cow.mp3 и импортировать новые модули, которые нам сейчас понадобились.
import audio
from key_codes import * #для константы EButton1Down
Теперь добавим «счетчик му». Создаем файл mu.txt, записываем в него цифру 0, и перемещаем в наш рабочий каталог.
В __init__ добавляем строку:
self.mu_count=int(open(data_path+'mu.txt').read())
Путь к файлу mu.txt не случайно находится в переменной data_path a не в app_path, позже при сборке в sis я расскажу зачем так сделано. В функцию say_mu, дописываем строки:
self.mu_count+=1
open(data_path+'mu.txt','w').write(str(self.mu_count))
Нам ведь нужно увеличивать счетчик мычаний и сохранять в файл.
Осталось вывести надпись на canvas и перерисовывать его принудительно после каждого мычания. И итоге у нас получается такой скрипт:
- #-*-coding:utf-8-*-
- import sys
- import e32
- from appuifw import *
- from graphics import *
- import audio
- from key_codes import *
- app_path=app.full_name()[0]+u':\\data\\python\\'
- data_path=app_path
- class Main:
- def __init__(self):
- self.mu_count=int(open(data_path+'mu.txt').read())
- app.directional_pad=False
- self.splash=Image.open(app_path+'splash.jpg')
- self.canvas=Canvas(redraw_callback=self.redraw)
- app.body=self.canvas
- self.canvas.bind(EButton1Down,self.say_mu,((44,171),(300,400)))
- self.mu=audio.Sound.open(app_path+'cow.mp3')
- def redraw(self,rect=None):
- self.canvas.blit(self.splash)
- self.canvas.text((30,465),text=u'Промычало %s раз.'%(self.mu_count),fill=0xffffff)
- def say_mu(self,event):
- if self.mu.state()==audio.EPlaying:
- self.mu.stop()
- self.mu.play()
- self.mu_count+=1
- open(data_path+'mu.txt','w').write(str(self.mu_count))
- self.redraw()
- lock=e32.Ao_lock()
- app.exit_key_handler=lock.signal
- a=Main()
- lock.wait()
Осталась самая малость, постить по желанию пользователя в twitter :)
Для этого нам понадобится библиотека tweepy (можно воспользоваться и другой, но эта мне больше всего понравилась).
Добавить возможность работы со сторонним модулем достаточно легко. Можно распаковать пакет в какую нибудь папку и добавить этот путь в sys.path. Так же эти сторонние модули можно упаковать в zip архив и импортировать прямо оттуда, что собственно говоря мы сейчас и сделаем. Скачиваем мною подготовленный архив (у tweepy зависимость от simplejson), помещаем его в наш рабочий каталог и добавляем в скрипт строки:
sys.path.append(app_path+'my_modules.zip')
import tweepy
Реализация добавления твита займет всего пару строчек:
def post_to_twitter(self):
name=query(u'Ваше имя:','text')
if not name:name=u'Аноним'
api = tweepy.API.new('basic', 'pys60_cow', 'pys60cow')
api.update_status(u'У пользователся %s корова промычала %s раз!'%(name,self.mu_count))
note(u'Твит добавлен!')
Не забудем создать меню, с одним единственным пунктом:
app.menu=[(u'Запостить твит',self.post_to_twitter)]
Теперь наш скрипт готов. И мы приступаем с следующей части нашей статьи.
Упаковка python скрипта в sis
Пора воспользоваться утилитой ensymble, которая идет в комплекте Python for s60. Запускаем это чудо утилиту.

Создаем где нибудь папочку для нашего проекта, например c:/temp/Pys60Cow, и помещаем туда файлы cow.py, cow.mp3, splash.jpg, my_modules.zip.
Переименовываем cow.py в default.py
Теперь поговорим о размещении файлов в установленной приложении.
Сам скрипт, с необходимыми ему файлами, такими как графика и пр. ляжет в папку x:/private/UID/, где x — диск, на который мы установим приложение, а UID — uid приложения. Эта папка доступна read only, поэтому данные приложения следует помещать в другую папку, например в x:/data/PyS60Cow/, поэтому мы и водили в нашу программу две переменные app_path и data_path. Теперь их нужно будет поменять на те, которые будут у нас использоваться в реальности.
В первую очередь сгенерируем валидный UID для программы. Для этого запускаем ensymble, выбираем Script directory, жмем browse и выбираем папку c:/temp/Pys60Cow. Запускаем упаковку по кнопке Create и видим окно с множеством предупреждений:

И вот он наш сгенериованный UID. Окрываем default.py и редактируем app_path и data_path:
app_path=app.full_name()[0]+u':\\private\\eecc323a\\'
data_path=app.full_name()[0]+u':\\data\\Pys60Cow\\'
Соответственно в ensymble нажимаем more, и в списке настроек, в поле uid вписываем 0xeecc323a. Так же мы сразу задать версия приложения в формате X.YY.ZZ
Теперь разберемся с папкой data/PyS60Cow, которая должна установится на смартфон и содержать файл mu.txt. В c:/temp/PyS60Cow создаем любую папку, например other, в ней директории с той структурой, которая должны быть на смартфоне. В нашем случае это подпапки data/PyS60Cow туда то и копируем файл mu.txt. В ensymble в настройке Additional Options прописываем опцию --extrasdir=other
Теперь пришла пора иконки. Иконка приложения для sis приложения должны быть в svg формате. Можете взять мою готовую иконку к этому приложению. Далее добавляем в Additional Options опцию --icon=путь_к_иконке например --icon=c:\temp\icon.svg
Нажимаем заветную кнопочку Create, устанавливаем получившийся sis пакет в наш смартфон и пытаемся запустить и видим ошибку о нехватке модуля cgi. Не беда, просто ensymble «забыла» положить этот модуль в sis пакет. Добавим его вручную, дописав в additional options --extra-modules=cgi. Собираем еще раз. Все теперь наше приложение готово, и радует наши пытливые умы :)
Скачать готовый sis файл можно отсюда, а папочку, готовую к упаковке, содержащую в себе скрипт, медиа файлы и пр., возьмите здесь