категории | RSS

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

Python на Symbian S60: словари и объект Form, вкладки пример FormBox.py

Объект Form - это диалоговое окно, элементы которого можно редактировать по своему усмотрению. Используется форма для вывода информации (свойств файла, например) и настройки программы. Каждый элемент формы состоит из названия и поля с данными (число, текст и т.д.).

Создание объекта
Form создается как обычный объект, при этом ему передаются аргументы, которые отвечают за его содержимое и вид:
>>> import appuifw
>>> form = appuifw.Form(fields [,flags])
>>>
Аргумент fields должен представлять список кортежей, каждый из которых отвечает за один элемент формы -[(label, type[, value ]),...]. Где:
1) label - название элемента (строка);
2) type - тип поля элемента (строка, варианты будет даны чуть ниже);
3) value - значение элемента по умолчанию (не обязателен).
Существуют следующие типы полей элементов формы:
1) «text» - текст;
2) «number» - целое число;
3) «float» - вещественное число;
4) «date» - дата;
5) «time» - время;
6) «combo» - список.
Аргумент flags (он необязательный) настраивает вид элементов формы и может принимать следующие значения:
FFormViewModeOnly
Устанавливает, что поля элементов формы доступны только для просмотра (их редактирование не допускается).
FFormEditModeOnly
Устанавливает, что поля элементов формы доступны и для редактирования.
FFormAutoLabelEdit
Разрешает возможность редактирования не только полей элементов, но и их названий.
FFormAutoFormEdit
Разрешает динамически изменять содержимое формы (т.е. удалять и добавлять элементы прямо по ходу работы).
FFormDoubleSpaced
Указывает представить элементы в двухстрочном виде: на первой строке расположено имя, на втором - поле.
Работа нескольких флагов одновременно организуется с помощью логической операции « | ».
После создания Form есть доступ к следующим атрибутам:
menu
Меню формы. Атрибуту необходимо присвоить список, состоящий из кортежей. Каждый кортеж отвечает за один пункт меню: [(title, callback),..]. Где: title - имя пункта, callback - имя функции, вызываемой сразу после нажатия на пункт. Меню должно быть только одноуровневым (т.е. никаких вложений). Кроме того, в случае когда установлен флаг FFormEditModeOnly (редактирования полей) появится пункт меню «Изменить».
save_hook
Этому атрибуту присваивается имя функции, которой передается единственный аргумент - содержимое формы. Задача save_hook - проверить верность введенных данных и вернуть логическое значение: True, если новое содержимое принимается как дозволенное, False - данные неприемлемы.
Также Form имеет несколько методов (функций то бишь):
execute()
Активирует форму, после чего она становится видимой и доступной для работы.
insert(index, field)
Вставляет новый элемент field после элемента с индексом index.
pop()
Возвращает значение последнего элемента и сразу же удаляет.
length()
Возвращает количество элементов формы.
Теперь рассмотрим практическую работу с формой. Во-первых, создадим список элементов (для наглядности имя элемента соответствую типу поля, также установлено значение по умолчанию):
>>> list = [
(u'text', 'text', u'\u0422\u0435\u043a\u0441\u0442'),
(u'number', 'number', 1024),
(u'float', 'float'),
(u'date', 'date', 1183755600.0),
(u'time', 'time', 21600.0),
(u'combo', 'combo', ([u'Symbian', u'Windows Mobile', u'Linux'], 2))]
>>>
Заметьте:
1) в текстовом поле использованы русские символы (Юникод);
2) элемент типа 'float' не может иметь значение по умолчанию;
3) при использовании типов 'date' и 'time' значения указываются в секундах;
4) в 'combo' использован кортеж, состоящий из списка строк (каждый из которых представляет собой один вариант выбора) и номера варианта, выделенное по умолчанию: ([label,...], index)
Пока никаких флагов не устанавливаем, поэтому сразу создадим форму и запустим :
>>> import appuifw
>>> form = appuifw.Form(list)
>>> form.execute()
>>>

Получили список одноуровневых элементов (имя, двоеточие и поле), но которые нельзя изменить. Этот вариант подходит в основном для вывода информации (например, свойства чего-либо). Для осуществления ввода данных необходимо установить флаг FFormEditModeOnly
>>> form = appuifw.Form(list, appuifw.FFormEditModeOnly)
>>> form.execute()
>>>
Если нужно больше места для имени и поля, можно использовать флаг FFormDoubleSpaced
>>> form = appuifw.Form(list, appuifw.FFormEditModeOnly | appuifw.FFormDoubleSpaced)
>>> form.execute()
>>>
После выхода из формы данные становятся доступны для просмотра -объект Form превращается в список полей:
>>> form[2]
1.33333
>>> form[5]
u'Symbian'
>>>
Первоначальные сведения об объекте Form я дал, теперь расскажу, как организовать в программе вкладки:
set_tabs(tab_texts[,callback=None])
Создаем вкладки, название которых содержится в списке tab_texts. Аргументу callback присваивается имя функции, вызываемой после каждого перехода по вкладкам. При этом передается аргумент в виде номера активированной вкладки. Переход по вкладкам происходит с использованием клавиш «Влево» и «Вправо».
>>> import appuifw
>>> def change(index):
... if index == 0:
... appuifw.app.body = appuifw.Text(u'Hello World!')
... elif index == 1:
... appuifw.app.body = appuifw.ListBox([u'One', u'Two'])
...
>>> list_tabs = [u'Text', u'List']
>>> appuifw.app.set_tabs(list_tabs, change)
>>> appuifw.app.activate_tab(0)
>>>
activate_tab(index)
Активирует вкладку под номером index.
На этом пока все, продолжу я статью рассказом о новом типе данных -словарь.
Создание и изменение словаря
Словарь - это последовательность, доступ к элементам которого производится по ключу. Ключами могут быть как числа, так и строки. По характеру работы словарь аналогичен своему книжному аналогу - например, англо-русский словарь: мы ищем в нем какое-то слово и получаем перевод.
Создается словарь путем перечисления пары ключ : значение через запятую, все это нужно заключить в фигурные скобки. Обращение к значению элемента производится только по ключу:
>>> dict = {'S' : 'Symbian', 'WM' : 'Windows Mobile'}
>>> dict['S']
'Symbian'
>>>
Примечание - если в словарь записывается несколько значений с одинаковым ключом, то сохраняется только последний:
>>> dict = {'S' : 'Symbian S60', 'WM' : 'Windows Mobile', 'S' : 'Symbian UIQ'}
>>> dict['S']
'Symbian UIQ'
>>>
У словаря можно получить длину функцией len(), удаляется запись с помощью оператора del, кроме того, словарь поддается изменению:
>>> dict = {'S' : 'Symbian', 'WM' : 'Windows Mobile', 'L' : 'Linux}
>>> len(dict)
3
>>> del dict['L']
>>> dict
{'S' : 'Symbian', 'WM' : 'Windows Mobile'}
>>> len(dict)
2
>>> dict['S'] = 'Symbian S60'
>>> dict['P'] = 'Palm'
>>> len(dict)
3
>>> dict
{'S' : 'Symbian S60', 'WM' : 'Windows Mobile', 'P' : 'Palm'}
>>>
Как вы могли обратить внимание, если при попытке изменить словарь мы обращаемся по несуществующему ключу (dict['P'] = 'Palm'), то создается новая запись ('P' : 'Palm'), т.е. это является одним из способов добавления новых элементов в словарь.

Методы словарей
clear()
Удаляет все записи из словаря:
>>> dict = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict.clear()
>>> dict
{}
>>>
copy()
Возвращает копию словаря:
>>> dict1 = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict2 = dict1.copy()
>>> dict2
{1:'One', 2:'Two', 3: Three'}
>>>
has_key(k)
Возвращает 1, если словарь содержит запись с ключом k:
>>> dict = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict.has_key(3)
1
>>> dict.has_key(4)
0
>>>
items()
Возвращает список записей в виде (key, value):
>>> dict = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict.items()
[(1, 'One'), (2, 'Two'), (3, 'Three)]
>>>
keys()
Возвращает список всех ключей:
>>> dict = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict.keys()
[1, 2, 3]
>>>
values()
Возвращает список всех значений:
>>> dict = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict.keys()
['One', 'Two', 'Three']
>>>
update(m)
Добавляет в словарь все записи словаря m:
>>> dict1 = {1 : 'One', 2 : 'Two', 3 : 'Three'}
>>> dict2 = {4 : 'Four', 5 : 'Five'}
>>> dict1.update(dict2)
>>> dict1
{1 : 'One', 2 : 'Two', 3 : 'Three', 4 : 'Four', 5 : 'Five'}
>>>
get(k [,v])
Возвращает значение с ключом k, но только если он есть, иначе возвращает значение v (по умолчанию None):
>>> dict = [1 : 'One', 2 : 'Two', 3 : 'Three']
>>> dict.get(3, 'Error')
'Three'
>>> dict.get(4, 'Error')
'Error'
>>>
setdefault(k [,v])
Возвращает значение с ключом k, если такого ключа нет, то метод возвращает значение v (по умолчанию None), при этом одновременно добавив в словарь новую запись k : v:
>>> dict = [1 : 'One', 2 : 'Two', 3 : 'Three']
>>> dict.setdefault(4, 'Four')
'Four'
>>> dict
{1 : 'One', 2 : 'Two', 3 : 'Three', 4: 'Four'}
>>>
Для закрепления теории приведу пример FormBox.py, где в интерактивном режиме можно изменить содержимое формы, причем все данные хранятся в словаре.

FormBox.py
Структура программы на этот раз необычная. В начале мы, как всегда, подключаем модули. Однако в конце переработано все.
Во-первых, мы создаем словарь, где уже вбит один элемент по умолчанию, и форму, где также имеется уже готовый элемент. Атрибуты информируют форму о возможности редактирования полей элементов и выделении каждому элементу по две строки:
dict = {u'Безымянный': u'Пусто'}
form = appuifw.Form([(u'Безымянный', 'text', u'Пусто')], appuifw.FFormAutoLabelEdit | appuifw.FFormDoubleSpaced)
Во-вторых, мы указываем форме вызывать функцию save_dict при каждом изменении и создаем меню (заметьте, пункт «Изменить» уже имеется по умолчанию):
form.save_hook = save_dict
form.menu = [
(u'Добавить', insert),
(u'Удалить', pop),
(u'Очистить', clear),
(u'Ключи keys),
(u'Значения', values),
(u'Проверка, has_key),
(u'Найти', get)]
В-третьих, изменили код проверки источника запуска программы. Теперь, при запуске примера из интерактивной консоли, изменяем подпись и нейтрализуем функцию выхода из программы (делаем ее «пустышкой» на основе lambda). В самом конце она будет вызваться, но если программа запущена из консоли, то ничего не произойдет. А вот если программа запущена из другого *.app приложения, то функция для выхода сработает на совесть (что нам и надо, так как иначе сама программа не закроется).
if appuifw.app.full_name().lower().find(u"python")!=-1:
appuifw.app.title=u'FormBox'
appuifw.app.set_exit=lambda:0
Также добавлен бесконечный цикл, который при выходе из формы запрашивает выход уже из программы. В случае положительного ответа команда break прервет выполнение цикла и сработает функция выхода, иначе вновь запустится форма (причем данные формы никуда не пропадут и все вернется обратно в целости и сохранности).
while 1:
form.execute()
if appuifw.query(u'Выйти из программы?', 'query'):
break
А теперь рассмотрим остальные функции в теле программы.
def save_dict(list):
global dict
dict={}
for index in list:
dict[index[0]]=index[2]
return True
Функция обновляет содержимое словаря в соответствии с новым содержимым формы:
1) делаем словарь пустым;
2) перебираем циклом все элементы полученного списка (напомню, аргументу функции передается содержимое формы в виде списка кортежей);
3) для каждого элемента формы создаем запись в словаре (ключом становится имя элемента - [0], значением - его поле [2]);
4) обязательно возвращаем True, чтобы форма приняла новое содержимое, иначе в случае возврата False все изменения отменятся;
def insert():
global dict
try:
key, volume = appuifw.multi_query(u'Название элемента:', u'Содержимое элемента:')
except:
pass
else:
dict[key]=volume
form.insert(len(dict)-1, (key, 'text', volume))
Функция для вставки нового элемента в форму:
1) получаем от пользователя название имени и содержимое поля будущего элемента формы;
2) если ввод был отменен, произойдет ошибка (при отмене возвращается None, а это не кортеж, и он не распаковывается - вот это и приведет к ошибке) и функция завершится;
3) иначе создаем в словаре новую запись;
4) вставляем в конец формы новый элемент.

def pop():
global dict
if len(dict)==1:
appuifw.note(u'Форма должна содержать хотя бы один элемент.', 'error')
return False
else:
element=form.pop()
del dict[element[0]]
return True
Функция для удаления последнего элемента формы:
1) если длина словаря равна единице, то информируем пользователя об ошибке (так как в форме должен быть минимум один элемент) и возвращаем False (зачем это, скажу ниже);
2) иначе получаем последний элемент формы и одновременно удаляем его;
3) удаляем из словаря значение по ключу (первый элемент кортежа) и возвращаем True.
def clear():
while pop():
pass
Функция для удаления всех элементов формы (хотя один по-любому останется). Представляет из себя бесконечный цикл для удаления элементов с конца и выполняется до тех пор, пока функция pop() не вернет False (т.е. больше элементов удалять уже нельзя). Именно для этого случая мы в вышеописанной функции и использовали return False/True, ведь для самого pop() они не нужны, а так убили двух зайцев и получили простейшую функцию.
def keys():
global dict
appuifw.query(u', '.join(dict.keys()), 'query')
Функция для вывода всех ключей из словаря. Преобразует список ключей в строку, при этом элементы списка соединяются между собой запятыми с помощью метода строки.
def values():
global dict
appuifw.query(u', '.join(dict.values()), 'query')
Функция для вывода всех значений в словаре (аналогичен вышеописанной функции).
def has_key():
global dict
key=appuifw.query(u'Введите имя элемента.', 'text', u'Безымянный')
if key:
if dict.has_key(key):
appuifw.note(u'Элемент с таким ключом существует.')
else:
appuifw.note(u'Нет элемента с таким ключом.', 'error')
Функция проверяет наличие в словаре элемента с заданным ключом:
1) получаем ключ от пользователя;
2) если ключ введен, то проверяем наличие ключа в словаре, и если такой существует, то информируем пользователя об этом;
3) если нет, то выводим соответствующее сообщение об ошибке.
На заметку - if key выполняется как if key!=None, т.е. на русском это звучит как «Если пользователь что-то ввел...»
def get():
global dict
key=appuifw.query(u'Введите имя элемента.', 'text', u'Безымянный)
if key:
appuifw.note(dict.get(key, u'Нет такого элемента.'))
Функция выводит значение элемента по его ключу:
1) запрашиваем ключ;
2) если он введен, демонстрируем найденное значение. Причем функция работает так, что если значения с таким ключом нет в словаре, то возвращается значение по умолчанию, если же такой ключ есть, то возвращается существующее значение.
Объект Form пригодится любому программисту. Можно просто осуществлять с помощью него настройку приложения, а можно вообще сделать форму главным элементом интерфейса вашей программы, т.е. как сделано в примере. Главное - грамотно использовать все методы объекта и удовлетворение пользователя будет гарантировано.

DimonVideo
2008-04-04T19:26:17Z
Здесь находятся
всего 0. За сутки здесь было 0 человек

Комментарии 2

#2   liosha2007    

Спасибо за статью. Хорошая..пригодится.smile


0 ответить

Яндекс.Метрика