Python на Symbian S60: объект Text, строки

Python на Symbian S60: объект Text, строки

Автор: Газетдинов Альберт

Источник: «Онлайн-журнал Mobi»

Объект Text представляет текстовое поле для ввода текста. Над текстом можно совершать простейшие операции: удалять (клавиша «C») и копировать/вставлять (удерживание клавиши «карандаш»). Не хватает только возможности изменения языка ввода (используется английский). Программист может усовершенствовать поле: сделать меню Функции, привязать к нажатиям на клавиши определенные события. Интерактивная консоль самого Python  – модифицированный вариант объекта Text, в ней наличествует меню, по нажатию на джойстик выполняется введенная команда.

Скачать пример TextBox.py

Создание объекта

Создается текстовое поле следующим способом:

>>> import  appuifw

>>> appuifw.app.body = body = appuifw.Text()

>>>

Объект находится в модуле appuifw, который подключаем к программе с помощью операции import. При этом новосозданный объект Text() становится текущим пользовательским интерфейсом (appuifw.app.body) – «телом» программы. Также при создании поля можно указать первоначальный текст. Облегчить способ обращения к созданному объекту можно, используя множественное присваивание:

>>> appuifw.app.body = Text = appuifw.Text(u’Hello!’)

>>>

Создаем текстовое поле Text.

Заметьте, весь текст должен быть в Unicode, т.е. можно вводить и выводить информацию на русском.

 

Методы и атрибуты объекта

Как и большинство объектов, Text имеет методы:

add(text)

Добавляет текст text после курсора.

>>> body.add(u’appuifw - Interface to the S60 GUI framework.’)

>>>

len()

Возвращает длину всего текста.

>>> body.len()

45

>>>

set(text)

Очищает поле и устанавливает его как text.

>>> body.set(u‘Wait…’)

>>> body.get()

u’Wait…’

>>>

get([pos = 0 ,length=len()])

Возвращает участок текста от позиции курсора pos и длиной length. По умолчанию pos равен нулю (начало текста), а length равен длине текста. Т.е. при вызове этого метода без аргументов возвращается весь текст.

>>> body.get()

u’appuifw - Interface to the S60 GUI framework.’

>>> body.get(10,19)

u’Interface’

>>>

delete([pos = 0 ,length=len()])

Удаляет участок текста от позиции курсора pos и длиной length. По умолчанию pos равен нулю (начало текста), а length равен длине текста. Т.е. при вызове этого метода без аргументов удаляется весь текст.

>>> body.delete(10,27)

>>> body.get()

u’appuifw - S60 GUI framework.’

>>>

clear()

Очищает текстовое поле.

>>> body.clear()

>>> body.get()

u’’

>>>

set_pos(pos)

Устанавливает текущую позицию курсора.

>>> body.set_pos(2)

>>> body.get_pos()

2

>>>

get_pos()

Возвращает текущую позицию курсора.

>>> body.get_pos()

7

>>>

bind(event_code, callback)

Привязывает к нажатию клавиши с кодом event_code вызов функции по имени callback. Как можно узнать код той или иной клавиши, будет сказано ближе к концу статьи.

Теперь перейдем к атрибутам объекта Text():

focus

Определяет, будет ли виден курсор. По умолчанию – True (т.е. виден мигающий курсор). Если ему присвоить значение False, то он перестанет быть видимым. На проведение операции (ввод, копирование) это никак не влияет.

font

Определяет шрифт выводимого текста:

>>> def fonts():

…          appuifw.app.body = body = appuifw.Text(u’Fonts:\n’)

…          for font in appuifw.available_fonts():

…               body.font = font

…               body.add(font+u’\n’)

>>> fonts()

>>>

Создаем текстовое поле Text
Результат работы функции fonts() – шрифты.

Примечание: мы использовали управляющий символ «\n» для того, чтобы каждая строка выводилась с новой строки.

color

Определяет цвет выводимого текста в виде кортежа из трех чисел (так называемая RGB): красная составляющая цвета, голубая и зеленая:

>>> def colors():

…       appuifw.app.body = body = appuifw.Text(u’Colors:\n’)

…       body.color = (0, 0, 0)

…       body.add(u’Black: (0, 0, 0)‘)

…       body.color = (255, 0, 0)

…       body.add(u’Red: (255, 0, 0)‘)

…       body.color = (0, 255, 0)

…       body.add(u’Blue: (0, 255, 0)‘)

…       body.color = (0, 0, 255)

…       body.add(u’Green: (0, 0, 255)‘)

>>> colors()

>>>

Создаем текстовое поле Text
Результат работы функции colors() – цветной текст.

highlight_color

Определяет цвет выделения (рассмотрено ниже).

style

Определяет стиль выводимого текста. Может принимать значение:

STYLE_BOLD

Текст получается жирным.

STYLE_UNDERLINE

Текст получается подчеркнутым

STYLE_ITALIC

Текст получается курсивом.

STYLE_STRIKETHROUGH

Текст получается перечеркнутый линией.

HIGHLIGHT_STANDARD

Текст получается выделенным.

HIGHLIGHT_ROUNDED

Текст получается с округленным выделением.

HIGHLIGHT_SHADOW

Текст получается с тенью.

Для объединения нескольких стилей используется логическая операция « | »:

>>> def  styles():

…       appuifw.app.body = body = appuifw.Text()

…       body.color = (0, 0, 0)

…       body.style = appuifw.STYLE_BOLD

…       body.add(u’STYLE_BOLD\n’)

…       body.color = (255, 0, 0)

…       body.style = appuifw.STYLE_UNDERLINE

…       body.add(u’STYLE_UNDERLINE\n’)

…       body.color = (0, 255, 0)

…       body.style = appuifw.STYLE_ITALIC

…       body.add(u’STYLE_ITALIC\n’)

…       body.color = (0, 0, 255)

…       body.style = appuifw.STYLE_STRIKETHROUGH

…       body.add(u’STYLE_STRIKETHROUGH\n’)

…       body.color = (255, 0, 255)

…       body.style = appuifw.STYLE_BOLD | appuifw.STYLE_UNDERLINE

…       body.add(u’STYLE_BOLD + STYLE_NDERLINE\n’)

…       body.color = (255, 255, 0)

…       body.style = appuifw.STYLE_BOLD | appuifw.STYLE_UNDERLINE | appuifw.STYLE_ITALIC

…       body.add(u’STYLE_BOLD + STYLE_NDERLINE + STYLE_ITALIC\n’)

…       body.color = (0, 255, 255)

…       body.style = appuifw.STYLE_BOLD | appuifw.STYLE_UNDERLINE | appuifw.STYLE_ITALIC | appuifw.STYLE_STRIKETHROUGH

…       body.add(u’STYLE_BOLD + STYLE_NDERLINE + STYLE_ITALIC + STYLE_STRIKETHROUGH\n’)

>>> styles()

>>>

Создаем текстовое поле Text
Результат работы функции styles – стили текста.

>>> def  highlights ():

…       appuifw.app.body = body = appuifw.Text()

…       body.color = (255, 0, 255)

…       body.highlight_color = (0, 255, 0)

…       body.style = appuifw.STYLE_BOLD | appuifw.HIGHLIGHT_STANDARD

…       body.add(u’STYLE_BOLD + HIGHLIGHT_STANDARD \n’)

…       body.color = (255, 255, 0)

…       body.highlight_color = (255, 0, 0)

…       body.style = appuifw.STYLE_UNDERLINE | appuifw.HIGHLIGHT_ROUNDED

…       body.add(u’STYLE_UNDERLINE + HIGHLIGHT_ROUNDED \n’)

…       body.color = (0, 255, 255)

…       body.highlight_color = (0, 0, 0)

…       body.style = appuifw.STYLE_ITALIC | appuifw.HIGHLIGHT_SHADOW

…       body.add(u’STYLE_ITALIC + HIGHLIGHT_SHADOW \n’)

>>> highlights ()

>>>

Создаем текстовое поле Text
Результат работы функции highlights – выделение.

 

На этом разговор об объекте Text() я закончу. А сейчас начнем изучение строк. Строки являются необходимым атрибутом любой программы – именно через них выводится вся информация. Даже если это число или список, все равно их надо будет преобразовать в строку. Итак, начнем со способов создания строк.

 

 

Создание строк

 

Строки создаются заключением текста в одинарные (‘’) или двойные кавычки (“”). Причем, открывающиеся и закрывающиеся кавычки должны быть одинаковы. Также можно использовать тройные кавычки (‘‘‘’’’ или “““”””), если начало и конец текста находится на разных строках:

>>> text = “““Hello!

… My name Albert”””

>>> print text

Hello!

My name Albert

>>>

Если вывести переменную text напрямую через консоль, то можно увидеть другую картину:

>>> text

>>> ‘Hello!\nMy name Albert’

Появился новый символ ‘\n’, и называется он управляющим. Используются управляющие символы для осуществления тех или иных действий при обработке строк. Так, символ ‘\n’ указывает переход на новую строку и дает возможность вводить многостраничные тексты в одну строку:

>>> text = ’I\nlove\you!’

>>> print text

I

love

you’

>>>

Создаем текстовое поле Text
Создаем строки.

 

Есть еще такие управляющие символы:

1) \\ –  символ обратно косой черты;

2) \’ – символ одинарной кавычки;

3) \” – символ двойной кавычки;

4) \r – символ возврата каретки;

5) \t – символ горизонтальной табуляции;

6) \v – символ вертикальной табуляции.

Строки можно «склеить» с помощью оператора «+» и «размножить» с помощью оператора «*»:

>>> text = ‘Hello’ + ‘ ’ + ‘world!’

>>> print text

>>> ‘Hello world!’

>>> text = ‘Help me! ’

>>> text * 3

>>> ‘Help me! Help me! Help me! ’

>>>

Cтроки, записанные друг за другом, автоматически объединяются:

>>> text = ‘Hello’ ‘ ’ ‘world!’

>>> print text

>>> ‘Hello world!’

>>>

Создаем текстовое поле Text
Склеиваем и размножаем строки.

 

По сути, строка в языке Python – последовательность символов с произвольным доступом. Это значит, что к любому символу можно обратиться по его номеру – индексу:

>>> text = ‘string’

>>> text[0]

‘s’

>>> text[-1]

g’

>>>

Если значение индекса меньше нуля, то отчет идет с конца строки.

Для облегчения восприятия приведу таблицу:

s t r i n g
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1

Из любой строки можно получить его подстроку с помощью среза. Срез – это два индекса, разделенные двоеточием и обозначающие начало и конец подстроки:

>>> text = ‘string’

>>> text[1:5]

trin

>>>

Т.е. мы получили подстроку начиная от 1 элемента (включительно) до 5 элемента (он в результат не включается). В срезе могут быть использованы отрицательные значения. Если какой-то индекс вообще опущен, то принимается значение по умолчанию: первый индекс принимается за ноль, второй – за длину строки:

>>> text = ‘string’

>>> text[:3]

‘str’

>>> text[3:]

‘ing’

>>> text[:]

‘string’

>>> text[-6:-3]

‘str’

>>> text[-3:]

ing’

>>>

Создаем текстовое поле Text
Строки во многом аналогичны спискам.

Обязательно потренируйтесь, чтобы понять, как работает срез, – это очень важный момент. Также запомните  – изменить строки нельзя! Это приведет к ошибке!

Прямое изменение строки можно заменить работой со срезами:

>>> text = ‘My name Python.’

>>> text[:8] + ’Albert’ + text[14]

My name Albert.’

>>>

У строки также можно определить длину с помощью функции len():

>>> text = ‘Hello!’

>>> len(text)

>>> 6

>>>

А теперь я перечислю методы, доступные для всех строк.

 

Форматирование

 

center(width)

Возвращает строку длиной width символов, в центре которой расположена исходная строка. Т.е. метод центрирует строку в поле заданной ширины. При этом строка дополняется с начала и с конца пробелами до нужной длины.

>>> text = ‘string’

>>> text.center(12)

‘   string   ‘

>>>

ljust(width)

Возвращает копию исходной строки, дополненную справа пробелами. Т.е. метод выравнивает строку влево в поле заданной ширины.

>>> text = ‘string’

>>> text.ljust(9)

‘string   ‘

>>>

rjust(width)

Возвращает копию исходной строки, дополненную слева пробелами. Т.е. метод выравнивает строку вправо в поле заданной ширины.

>>> text = ‘string’

>>> text.rjust(9)

‘   string‘

>>>

В функциях center(), ljust(), rjust(), если width меньше длины исходной строки, то она возвращается без изменений.

 

Разбиение и объединение

 

join(sep)

Возвращает объединение строк последовательности, используя исходную строку в качестве разделителя. Если последовательность содержит элементы, которые не являются строками, происходит ошибка.

>>> list = [‘My’, ‘name’, ‘Albert’]

>>> ‘ ‘.join(list)

‘My name Albert‘

>>>

split([sep [,maxcount]])

Возвращает список слов, содержащихся в исходной строке. В качестве разделителя слов используется строка sep. Если она не задана, разделителем слов считаются символы пропуска. Если задан аргумент maxcount, причем maxcount >= 0, то возвращается список из maxcount первых слов.

>>> text = ‘My name Albert‘

>>> text.split()

[‘My’, ‘name’, ‘Albert’]

>>> text.split(‘’, 2)

[‘My’, ‘name’]

>>>

splitlines([keepends])

Аналог метода split(), но использующий в качестве разделителя переход на новую строку. Символы перехода на новую строку включаются в результат, только если необязательный аргумент keepends равен 1.

>>> text = “““Hello World!

Hello Albert!”””

>>> text.splitlines()

[‘Hello World!’, ‘Hello Albert!’]

>>>

 

Поиск вхождений

 

count(sub [, start [, end]])

Возвращает количество вхождений строки sub (т.е. сколько оно раз встречается) в исходной строке.

>>> text = ‘Help me! Help!’

>>> text.count(‘Help’)

2

>>>

startswith(prefix [, start [, end]])

Возвращает 1, если исходная строка начинается на prefix, иначе – 0.

>>> text = ‘Help me!’

>>> text.startswith(‘help’)

0

>>> text.startswith(‘Help’)

1

>>>

endswith(suffix [, start [, end]])

Возвращает 1, если исходная строка оканчивается на suffix, иначе – 0.

>>> text = ‘Help me!’

>>> text.endswith(‘me’)

0

>>> text.endswith(‘me!’)

1

>>>

find(sub [, start [, end]])

Возвращает наименьший индекс строки sub в исходной строке. Если строка не найдена, возвращается –1.

>>> text = ‘Help me! Help!’

>>> text.find (‘Help’)

0

>>>

rfind(sub [, start [, end]])

Возвращает наибольший индекс строки sub в исходной строке. Если строка не найдена, возвращается –1.

>>> text = ‘Help me! Help!’

>>> text.rfind (‘Help’)

9

>>>

index(sub [, start [, end]])

Аналог метода find(), но генерирует исключение, если строка sub не найдена.

rindex(sub [, start [, end]])

Аналог метода rfind(), но генерирует исключение, если строка sub не найдена.

В функциях count(), startswith(), endswith(), find(), rfind(), index(), rindex() необязательные аргументы start и end интерпретируются как индексы в операции среза исходной строки.

 

Преобразование символов и строк

 

expandtabs([tabsize])

Возвращает копию исходной строки. В ней символы табуляции заменены одним или несколькими пробелами в зависимости от выбранного размера табуляции. По умолчанию размер табуляции tabsize равен 8 символам.

>>> text = ‘        string        ’

>>> text.expandtabs()

string‘

>>>

lstrip()

Возвращает копию исходной строки, с удаленными идущими в начале символами пропуска.

>>> text = ‘        string        ’

>>> text.lstrip()

string        ‘

>>>

rstrip()

Возвращает копию исходной строки, с удаленными идущими в конце символами пропуска.

>>> text = ‘        string        ’

>>> text.rstrip()

‘        string‘

>>>

strip()

Возвращает копию исходной строки, с удаленными идущими в начале и в конце символами пропуска.

>>> text = ‘        string        ’

>>> text.strip()

‘string‘

>>>

replace(old, new [maxcount])

Возвращает копию строки, в которой все вхождения строки old заменены на new. Если задан необязательный аргумент maxcount, заменяются только первые maxcount вхождений.

>>> text = ‘Help! Help! Help!’

>>> text.replace(‘Help’, ’Go’)

Go! Go! Go!‘

>>>

capitalize()

Возвращает копию исходной строки, в которой первая буква заменена на прописную.

>>> text = ‘hello!’

>>> text.capitalize()

Hello!’

>>>

swapcase()

Возвращает копию исходной строки, в которой регистр букв изменен с верхнего на нижний и наоборот.

>>> text = ‘Hello!’

>>> text.swapcase()

hELLO!’

>>>

lower()

Возвращает копию исходной строки, все символы которой приведены к нижнему регистру.

>>> text = ‘Hello!’

>>> text.lower()

hello!’

>>>

upper()

Возвращает копию исходной строки, все символы которой приведены к верхнему регистру.

>>> text = ‘Hello!’

>>> text.upper()

HELLO!’

>>>

title()

Возвращает копию исходной строки, в которой регистр букв соответствует заголовку.

>>> text = ‘Hello!’

>>> text.title()

‘HELLO!’

>>> text = ‘hELLO!’

>>> text.title()

hello!’

>>>

istitle()

Возвращает 1, если регистр букв в исходной строке соответствует заголовку, иначе возвращает 0.

>>> text = ‘Hello!’

>>> text.istitle()

0

>>> text = ‘hello!’

>>> text.istitle()

1

>>>

islower()

Возвращает 1, если все символы в исходной строке находятся в нижнем регистре (строчные), иначе возвращает 0.

>>> text = ‘HELLO!’

>>> text.islower()

0

>>> text = ‘hello!’

>>> text.islower()

1

>>>

isupper()

Возвращает 1, если все символы в исходной строке находятся в верхнем регистре (прописные), иначе возвращает 0.

>>> text = ‘HELLO!’

>>> text.isupper()

1

>>> text = ‘hello!’

>>> text.isupper()

0

>>>

isdigit()

Возвращает 1, если исходная строка содержит только цифры, иначе возвращает 0.

>>> text = ‘I have 2 apple.’

>>> text.isdigit()

0

>>> text = ‘2007’

>>> text.isdigit()

1

>>>

isspace()

Возвращает 1, если исходная строка содержит только символы пропуска – пробел, табуляция, перевод на новую строку и т. д., иначе возвращает 0.

>>> text = ‘Hello!

>>> text.isspace()

0

>>> text = ‘        ’

>>> text.isspace()

1

>>>

decode(type)

Возвращает строку в Unicode, полученную после преобразования исходной строки в кодировке type. Например, если мы имеем текстовый файл, написанный в формате UTF-8, то для вывода информации на экран прежде его необходимо преобразовать:

>>> text = ‘\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82’ # ‘Привет!’ в UTF-8

>>> text.decode(‘utf-8’)

u’ \u041f\u0440\u0438\u0432\u0435\u0442!’

>>>

encode(type)

Возвращает строку в кодировке type, полученную после преобразования исходной строки в Unicode.

>>> text = u’ \u041f\u0440\u0438\u0432\u0435\u0442!’ # ‘Привет!’ в Unicode

>>> text.encode(‘utf-8’)

‘\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82’

>>>

Вы, наверно, не ожидали, что с обычной строкой можно осуществить столько действий. Чтобы закрепить урок, я написал обучающую программу TextBox.py. Я объясню, как работает программа.

 

TextBox.py

 

Скачать пример TextBox.py

Функционал программы строится из следующих частей:

1) атрибуты текста;

2) форматирование;

3) преобразование;

4) поиск.

Программа начинается со строки import e32,appuifw, key_codes с помощью которой подключаем к программе модули e32 (сервисные функции), appuifw (создание интерфейса) и key_codes (коды клавиш). Затем создаем объект Text и устанавливаем как текущий пользовательский интерфейс. В дальнейшем сможем обращаться к нему напрямую через appuifw.app.body.

С помощью метода bind() привязываем к нажатию на клавишу Вызов запуск функции очистки экрана:

appuifw.app.body.bind(key_codes.EKeyYes, appuifw.app.body.clear)

Имена клавиш находятся в модуле key_codes. Кроме EKeyYes, отвечающий за нажатие на клавишу Вызов, доступно:

1) EKeyLeftSoftkey – нажатие на левую-софт клавишу;

2) EKeyRightSoftkey – нажатие на правую-софт клавишу;

3) EKeyMenu – нажатие на кнопку Меню;

4) EKey0...9 – нажатие на цифровые клавиши 0-9;

5) EKeyStar – нажатие на клавишу «*»;

6) EKeyHash – нажатие на клавишу «#»;

7) EKeyLeftArrow – нажатие Влево;

8) EKeyRightArrow  – нажатие Вправо;

9) EKeyDownArrow  – нажатие Вниз;

10) EKeyUpArrow  – нажатие Вверх;

11) EKeySelect  – нажатие в центр джойстика (Выбор);

12) EKeyEdit – нажатие на клавишу «карандаш»;

13) EKeyBackspace – нажатие на клавишу «С»;

14) EKeyNo – нажатие на клавишу Отбой.

Можно написать код перехватываемой клавиши. О последней можно узнать из программы keyviewer.py (идет вместе с Python) – запустите, нажмите интересующую клавишу и увидите код «Scancodes of pressed key:».

Заканчивается программа несколькими блоками кода. Во-первых, создаем функцию exit для запроса подтверждения при входе из программы и привязываем её к нажатию на кнопку Выход (appuifw.app.exit_key_handler):

def exit():

if appuifw.query(u’Выйти из программы?’, ‘query’):

os.abort()

appuifw.app.exit_key_handler=exit

В действительности мы использовали еще один модуль (os) для функции abort(). Причина – нестабильная работа встроенной функции appuifw.app.set_exit() для выхода из программы на Symbian 9 (например, на Nokia 6120 реакция на нее вызов отсутствует). Выход же по функции os.abort() гарантирован.

Создаем текстовое поле Text
Обязательное подтверждение выхода.

Во-вторых, описываем меню Функции с помощью присваивания переменной appuifw.app.menu списка с описанием всех пунктов. Обратите внимание на организацию: каждый пункт меню находится на отдельной строке, если пункт меню вложенный, то это отражается отступом. Все это дает возможность лучше понять структуру меню любой программы:

appuifw.app.menu = [

(u’ Атрибуты текста’,(

(u’шрифт текста’, font)

(u’цвет текста’, color)

(u’цвет заливки’, highlight_color)

(u’стиль текста’, style_text)

(u’стиль заливки’, style_high))),

(u’Форматирование’,(

(u’центрировать’, lambda:format('center'))

(u’по левому краю’, lambda:format('ljust'))

(u’по правому краю’, lambda:format('rjust')))),

(u’Преобразование’,(

(u’все прописные’, lambda:registr('upper’))

(u’все строчные’, lambda: registr('lower’))

(u’ивертировать’, lambda: registr('swapcase’)))),

(u’Поиск’,(

(u’кол-во слов’, lambda:appuifw.note(u'Всего слов:\n'+unicode(len( appuifw.app.body.get().split())))),

(u’найти слово’, count)

(u’заменить’, replace)),

(u’Дополнительно’,(

(u'фокус', focus),

(u’длина текста’, lambda:appuifw.note(unicode(appuifw.app.body.len()))),

(u'удалить до курсора', lambda:delete(-1)),

(u'удалить после курсора', lambda:delete(1)))),

(u’Выйти’, exit)]

Создаем текстовое поле Text
Меню программы TextBox.py

В-третьих, определяем, откуда запущена программа. Есть два варианта: либо через интерактивную консоль, либо как самостоятельное приложение (запуск по ярлыку из Меню). Чтобы не писать две разные программы, приведу код, который осуществляет проверку автоматически и подстраивается под ситуацию.

Сначала воспользуемся функцией e32.full_name() и с помощью среза «вырежем» имя файла:

if appuifw.app.full_name()[-10:-4] == u'Python'

Если это ‘Python.app’, то программа запущена из интерактивной консоли и необходимо использовать метод wait() объекта Ao_lock для прерывания выполнения программы (если этого не сделать, то после запуска мы заметим только, как мигнет экран, и программа завершится). Соответственно, для перехода из программы (с помощью appuifw.app.set_exit) обратно в интерактивную консоль нам необходимо будет вызвать метод signal(). Зачем это нужно? Если бы не сделали эту проверку и сразу написали бы lock.wait(), то при запуске программы из Меню на телефонах Symbian 8.1 (Nokia n70, N72, N90) наблюдались бы неприятные искажения рабочего стола (пропали бы часы, уровни сети и зарядки, статусная строка). Нелишне определиться и с подписью приложения (переменная appuifw.app.title).

appuifw.app.title == u’TextBox’

lock = e32.Ao_lock()

os.abort = lock.signal

lock.wait()

Если программа запущена из меню, то все проще – блокировка не нужна, подпись установится сама, для выхода используем функцию os.abort().

Опишу остальные функции программы.

def error(text):

appuifw.note(text, 'error')

def conf(text):

appuifw.note(text, 'conf')

Эти две функции позволяют быстро написать код для вывода информации об ошибке (error) и завершении операции (conf).

def font():

fonts=appuifw.available_fonts()

index=appuifw.popup_menu(fonts, u'Выберите шрифт:')

if index>=0:

try:

appuifw.app.body.font = fonts[index]

except:

error(u'Ошибка при установке шрифта.’)

else:

conf(u'Шрифт установлен.’)

Функция для установки шрифта:

1) получаем список шрифтов;

2) просим пользователя выбрать нужный шрифт из списка;

3) если выбор сделан, то шрифт применяется к интерфейсу (у нас интерфейс представлен объектом Text);

4) если шрифт не может быть установлен, то происходит ошибка, о чем программа сообщает;

5) если все прошло успешно, появляется сообщение об успешном проведении операции.

Создаем текстовое поле Text
Выбираем понравившийся шрифт.
Создаем текстовое поле Text
Результат видим сразу.

def color():

colors=appuifw.query(u'Введите цвет RGB через запятую:','text', u'255, 0, 255')

if len(colors)>=0:

try:

appuifw.app.body.color = eval('('+colors+')')

except:

error(u'Ошибка при установки цвета.’)

else:

conf(u'Цвет установлен.')

def highlight_color():

highlight_colors=appuifw.query(u'Введите цвет RGB через запятую:','text', u'0, 255, 0')

if len(highlight_colors)>=0:

try:

appuifw.app.body.highlight_color = eval('('+highlight_colors+')')

except:

error(u'Ошибка при установки цвета.’)

else:

conf(u'Цвет установлен.')

Две функции для установки цвета шрифта и заливки:

1) запрашиваем у пользователя цвет в виде RGB (красная, зеленая и синяя составляющая цвета, пишутся через запятую);

2) если цвет введен (т.е. длина строки больше нуля), то преобразуем текст в кортеж и присваиваем атрибуту color (или highlight_color);

3) если произошла ошибка, появляется соответствующее сообщение;

4) если все прошло успешно, появляется сообщение об успешном проведении операции.

Создаем текстовое поле Text
Установили цвет текста.
Создаем текстовое поле Text
Результат видим сразу.

def style_text():

styles=[u'STYLE_BOLD', u'STYLE_UNDERLINE', u'STYLE_ITALIC', u'STYLE_STRIKETHROUGH']

index=appuifw.popup_menu(styles, u'Выберите стиль:')

if index>=0:

appuifw.app.body.style=eval('appuifw.'+styles[index])

conf(u'Стиль установлен.')

def style_high():

styles=[u'HIGHLIGHT_STANDARD', u'HIGHLIGHT_ROUNDED', u'HIGHLIGHT_SHADOW']

index=appuifw.popup_menu(styles, u'Выберите стиль:')

if index>=0:

appuifw.app.body.style=eval('appuifw.'+styles[index])

conf(u'Стиль установлен.')

Две функции для установки стилей шрифта и выделения:

1) создаем список стилей;

2) просим пользователя выбрать из списка нужный стиль;

3) преобразуем стиль в переменную модуля appuifw в переменную и применяем к атрибуту style;

4) если все прошло успешно, появляется сообщение об успешном проведении операции.

Создаем текстовое поле Text
Стиль текста STYLE_BOLD.
Создаем текстовое поле Text
Стиль заливки STYLE_ROUNDED.

def format(name):

width=appuifw.query(u'Ширина будущей строки:', 'number', 8)

if width>=0:

string=appuifw.app.body.get()

string=eval('string.'+name+'(width)')

appuifw.app.body.set(string)

#appuifw.app.body.set(eval('appuifw.app.body.get().'+name+'(width)'))

conf(u'Операция проведена успешно.')

Эта функция – вкупе с lambda – заменяет сразу три функции и служит примером того, как можно оптимизировать код. При этом она имеет аргумент, в зависимости от которого будет демонстрировать разный результат. Сам же аргумент передается соответствующей lambda-функцией прямо из Меню.

1) Получаем от пользователя ширину будущей строки;

2) если ширина указана, получаем  текст из поля;

3) преобразуем его с использованием метода, название которого передано функции в виде аргумента name;

4) устанавливаем преобразованный текст как новое содержимое поля;

5) уведомляем пользователя об успешности проведения операции.

Заметьте! Код, скрытый комментарием, может заменить три вышестоящих строки. Таким образом, функция «худеет» наполовину без потери функциональности – еще один пример хорошей оптимизации.

Создаем текстовое поле Text
Выравниваем текст по центру.
Создаем текстовое поле Text
Смотрим на результат.

Выравниваем текст по центру.

def registr(name):

appuifw.app.body.set(eval('appuifw.app.body.get().'+name +'()'))

Эта функция оптимизирована до предела: мало того, что она заменяет три функции для выравнивания текста, так сам код функции укорочен втрое – по примеру предыдущей функции. Для наглядности я «разверну» эту строку:

string=appuifw.app.body.get()

string=eval(''appuifw.app.body.get().'+name+'()')

appuifw.app.body.set(string)

Создаем текстовое поле Text
Делаем все буквы прописными.

lambda:appuifw.note(u'Всего слов:\n'+unicode(len(appuifw.app.body.get().split())))

Функция для определения количества слов «вморожена» с помощью lambda в само меню. Этот способ экономит кучу места, но применяется только теми программистами, которые более-менее освоились в Python. Для тех, кто не принадлежит к такой группе, я расшифрую данный код:

text = appuifw.app.body.get()

list = text.split()

list_len = len(list)

out = unicode(list_len)

appuifw.note(u'Слов в тексте:\n'+out)

Расшифровываю:

1) получаем весь введенный пользователем текст из поля;

2) делим текст на слова, разделенные пробелом;

3) определяем длину полученного списка, т.е. получаем количество слов;

4) преобразуем число в строку для вывода;

5) выводим сообщение с указанием количества слов в тексте.

def find():

text=appuifw.query(u'Найти данное слово:', 'text')

if len(text)>=0:

index=appuifw.app.body.get().find(text)

if index == -1:

appuifw.app.body.set_pos(index)

conf(u' Курсор переведен на начало найденного слова.')

else:

error(u' Слово не найдено.')

Функция для поиска слова в тексте:

1) получаем от пользователя слово для поиска;

2) если слово введено, то ищем во введенном пользователем тексте слово и получаем его позицию;

3) если слово найдено (позиция не равна -1), то переводим курсор на эту позицию;

4) уведомляем пользователя об этом;

5) иначе – сообщаем, что слово не найдено.

def replace():

old,new=appuifw.multi_query(u'Этот текст:',u'Заменить на:')

if len(old)>=0 and len(new)>=0:

appuifw.app.body.set(appuifw.app.body.get().replace(old, new))

conf(u'Замена проведена.')

Функция заменяет один текст на другой:

1) получаем от пользователя старую и новую строку;

2) если обе строки введены (используется логическая операция and), то получаем текст, производим замену и отображаем измененный текст;

3) сообщаем об успешности проведения операции.

def focus():

if appuifw.app.body.focus == False:

appuifw.app.body.focus = True

else:

appuifw.app.body.focus = False

Функция инвертирует состояние курсора:

1) если курсор виден, то скрываем его;

2) иначе – показываем.

def delete(mode):

pos=appuifw.app.body.get_pos()

if mode==-1:

appuifw.app.body.delete(0, pos)

elif mode==1:

appuifw.app.body.delete(pos)

conf(u'Текст удален.')

Функция удаляет текст до или после курсора (в зависимости от параметра, передаваемой lambda-функцией):

1) получаем текущую позицию курсора;

2) если аргумент равен -1, то удаляем текст от начала и до позиции курсора;

3) если аргумент равен 1, то удаляем текст от позиции курсора и до конца.

4) информируем о завершении операции.

На этом все. Учитесь, экспериментируйте и ждите следующую статью.

Скачать пример TextBox.py