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

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

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

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

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)

Пока никаких флагов не устанавливаем, поэтому сразу создадим форму и запустим (Рис. 1):

>>> import appuifw

>>> form = appuifw.Form(list)

>>> form.execute()

>>>

Рис. 1. Форма активирована.

 

Получили список одноуровневых элементов (имя, двоеточие и поле), но которые нельзя изменить. Этот вариант подходит в основном для вывода информации (например, свойства чего-либо). Для осуществления ввода данных необходимо установить флаг FFormEditModeOnly (Рис. 2).

>>> form = appuifw.Form(list, appuifw.FFormEditModeOnly)

>>> form.execute()

>>>

Рис. 2. Элементы формы поддаются изменению.

Если нужно больше места для имени и поля, можно использовать флаг FFormDoubleSpaced (Рис. 3–4)

>>> form = appuifw.Form(list, appuifw.FFormEditModeOnly | appuifw.FFormDoubleSpaced)

>>> form.execute()

>>>

Рис. 3. Стало больше места.   

Рис. 4. Стало больше места.

После выхода из формы данные становятся доступны для просмотра – объект 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)

>>>

Рис 5. Первая вкладка.    

Рис. 6. Вторая вкладка.

 

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’), т.е. это является одним из способов добавления новых элементов в словарь.

Рис. 7. Создаем словарь и изменяем его.  

Методы словарей

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

Скачать пример 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)]

Рис. 8. Меню функции FormBos.py.

В-третьих, изменили код проверки источника запуска программы. Теперь, при запуске примера из интерактивной консоли, изменяем подпись и нейтрализуем функцию выхода из программы (делаем ее «пустышкой» на основе 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) вставляем в конец формы новый элемент.

Рис. 9. Вставляем новые элементы.   

Рис. 10. Пара штук успешно добавилась.

 

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, т.е. на русском это звучит как «Если пользователь что-то ввел…»

Рис. 11. Ищем значение по его ключу (проще говоря, имени).

def get():

global dict

key=appuifw.query(u'Введите имя элемента.', 'text', u'Безымянный)

if key:

appuifw.note(dict.get(key, u'Нет такого элемента.'))

Функция выводит значение элемента по его ключу:

1) запрашиваем ключ;

2) если он введен, демонстрируем найденное значение. Причем функция работает так, что если значения с таким ключом нет в словаре, то возвращается значение по умолчанию, если же такой ключ есть, то возвращается существующее значение.

Объект Form пригодится любому программисту. Можно просто осуществлять с помощью него настройку приложения, а можно вообще сделать форму главным элементом интерфейса вашей программы, т.е. как сделано в примере. Главное – грамотно использовать все методы объекта и удовлетворение пользователя будет гарантировано.

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






Рекомендуемый контент




Copyright © 2010-2017 housea.ru. Контакты: info@housea.ru При использовании материалов веб-сайта Домашнее Радио, гиперссылка на источник обязательна.