Read the book: «Разработка кроссплатформенных мобильных и настольных приложений на Python. Практическое пособие», page 3
Краткие итоги
В этой главе мы познакомились с основными инструментальными средствами, с помощью которых можно разрабатывать кроссплатформенные приложения на языке программирования Python, как для настольных компьютеров, так и для мобильных устройств. Это интерпретатор Python, интерактивная среда разработки программного кода PyCharm, фреймворк Kivy и библиотека KivyMD. Установив на свой компьютер эти инструментальные средства уже можно приступать к написанию программного кода, что мы и сделали, написав несколько простейших программ.
Теперь можно перейти к следующей главе и более детально познакомиться с фреймворком Kivy, с особенностями встроенного языка KV, а также с основными виджетами, которые используются для создания пользовательского интерфейса.
Глава 2. Фреймоворк Kivy, язык KV и виджеты, как основа пользовательского интерфейса
В этой главе мы рассмотрим вопросы, связанные с особенностями приложений, написанных с использованием фреймворка Kivy. Познакомимся с языком KV, и с виджетами – контейнерами, которые обеспечивают позиционирование элементов интерфейса на экране. В частности, будут рассмотрены следующие материалы:
– особенности фреймворка Kivy и общие представления о дереве виджетов;
– базовые понятия о синтаксисе языка KV и возможности создания пользовательских классов и объектов;
– возможности разделения приложений на логически и функционально связанные блоки;
– понятия о свойствах и параметрах виджетов;
– описание виджетов, используемых для позиционирования видимых элементов интерфейса.
Итак, приступим к знакомству с основами работы с фрейморком Kivy.
2.1. Общее представление о фрейморке Kivy
Фреймворк Kivy – это кроссплатформенная бесплатная библиотека Python с открытым исходным кодом. С ее использованием можно создавать приложения для любых устройств (настольные компьютеры, планшеты, смартфоны). Данный фреймворк заточен на работу с сенсорными экранами, однако приложения на Kivy с таким же успехом работают и на обычных мониторах. Причем даже на устройстве с обычным монитором приложение будет вести себя так, как будто оно имеет сенсорный экран. Kivy работает практически на всех платформах: Windows, OS X, Linux, Android, iOS, Raspberry Pi.
Этот фрейморк распространяется под лицензией MIT (лицензия открытого и свободного программного обеспечения) и на 100% бесплатен для использования. Фреймворк Kivy стабилен и имеет хорошо документированный API. Графический движок построен на основе OpenGL ES2.
Примечание.
OpenGL ES2 – подмножество графического интерфейса, разработанного специально для встраиваемых систем (мобильные телефоны, мини компьютеры, игровые консоли).
В набор инструментов входит более 20 виджетов, и все они легко расширяемы.
Примечание.
Виджет – это небольшое приложение для компьютера или смартфона, которое обычно реализуется в виде класса и имеет набор свойств и методов. Через виджеты обеспечивается взаимодействие приложения с пользователем. Виджет может быть видимым в окне приложения, а может быть скрытым. Но даже в скрытом виджете запрограммирован определенный набор функций.
При использовании фрейморка Kivy программный код для создания элементов пользовательского интерфейса можно писать на Python, а можно для этих целей использовать специальный язык. В литературе можно встретить разное обозначение этого языка: язык kivy язык KV, KV. Далее во всех разделах этой книги он будет обозначен, как KV.
Язык KV обеспечивает решение следующих задач:
– создавать объекты на основе базовых классов Kivy.
– формировать дерево виджетов (создавать контейнеры для размещения визуальных элементов и указывать их расположение на экране);
– задавать свойства для виджетов;
– естественным образом связывать свойства виджетов друг с другом;
– связывать виджеты с функциями, в которых обрабатываются различные события.
Язык KV позволяет достаточно быстро и просто создавать прототипы программ и гибко вносить изменения в пользовательский интерфейс. Это также обеспечивает при программировании отделение логики приложения от пользовательского интерфейса.
Есть два способа загрузить программный код на KV в приложение.
– По соглашению об именах. В этом случае Kivy ищет файл с расширением». kv» и с тем же именем, что и имя базового класса приложения в нижнем регистре, за вычетом символов «App». Например, если базовый класс приложения имеет имя MainApp, то для размещения кода на языке KV нужно использовать файл с именем main. kv. Если в этом файле задан корневой виджет, то он будет использоваться в качестве основы для построения дерева виджетов приложения.
– С использованием специального модуля (компоненты) Builder можно подключить к приложению программный код на языке KV либо из строковой переменной, либо из файла с любым именем, имеющем расширение». kv». Если в данной строковой переменной или в этом файле задан корневой виджет, то он будет использоваться в качестве основы для построения дерева виджетов приложения.
У компоненты Builder есть два метода для загрузки в приложение кода на языке KV:
– Builder. load_file (’path/name_file. kv’) – если код на языке KV подгружается из файла (здесь path – путь к файлу, name_file. kv – имя файла);
– Builder. load_string (kv_string) – если код на языке KV подгружается из строковой переменной (kv_string – имя строковой переменной).
2.2. Язык KV и его особенности
2.2.1. Классы и объекты
По мере того, как приложение усложняется, становится трудно поддерживать конструкцию дерева виджетов и явное объявление привязок. Чтобы преодолеть эти недостатки, альтернативой является язык KV, также известный как язык Kivy или KVlang. Язык KV позволяет создавать дерево виджетов в декларативной манере, позволяет очень быстро создавать прототипы и оперативно вносить изменения в пользовательский интерфейс. Это также помогает отделить логику приложения от пользовательского интерфейса.
Язык KV, как и Python, является объектно-ориентированным языком. Все элементы интерфейса представляют собой объекты, которые строятся на основе базовых классов. Каждый класс имеет набор свойств, зарезервированных методов и событий, которые могут быть обработаны с помощью функций. В языке KV принято соглашение: имя класса всегда начинается с заглавной буквы (например, Button – кнопка, Label – метка), а имя свойства с маленькой буквы (например, text, text_size, font_size).
Самый простой способ использования классов в KV – это употребление их оригинальных имен. Проверим это на простом примере. Создадим файл с именем K_May_Class1.py и напишем в нем следующий код (листинг 2.1).
Листинг 2.1. Пример использования базового класса (модуль K_My_Class1.py)
# модуль K_May_Class1.py
from kivy. app import App
from kivy.lang import Builder
KV =«»»
BoxLayout: # контейнер (базовый класс BoxLayout)
……Button: # кнопка (класс Button)
…… … … text: «Кнопка 1» # свойство кнопки (надпись)
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Примечание.
Мы еще не знакомились с виджетами Kivy, а в этом коде используется два виджета: видимый виджет Button (кнопка), и виджет – контейнер BoxLayout (коробка). Более подробно о них будет сказано в последующих разделах. А пока будем использовать их в своих примерах. В листинге присутствуют тройные кавычки – «»», в редакторе программного кода вместо них нужно использовать тройной апостроф – «'''».
В этом коде в текстовой переменной KV создан виджет – контейнер на основе базового класса BoxLayout, в нем размещена кнопка (Button), свойству кнопки text присвоено значение «Кнопка 1» (на языке KV свойство от его значения отделяется знаком двоеточия «:»). При этом нет необходимости явно импортировать базовые классы, они загрузятся автоматически. После запуска приложения получим следующий результат (рис.2.1).

Рис. 2.1. Результаты выполнения приложения из модуля K_May_Class1.py
В этом примере мы косвенно познакомились с виджетом – контейнером BoxLayout и простейшим деревом виджетов. Здесь в виджет – контейнер была помещена кнопка. Более подробно виджеты – контейнеры будут рассмотрены в последующих разделах.
Разработчик может в коде на Python переопределить имя базового класса, то есть создать собственный пользовательский класс. Например, разработчик хочет использовать класс BoxLayout, но при этом дать ему другое имя, например, MyBox. Проверим это на простом примере. Создадим файл с именем K_May_Class2.py и напишем в нем следующий код (листинг 2.2).
Листинг 2.2. Пример использования пользовательского класса (модуль K_My_Class2.py)
# модуль K_May_Class2.py
from kivy. app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
KV = «»»
MyBox: # контейнер (пользовательский класс)
……Button: # кнопка (класс Button)
…… … …text: «Кнопка 2» # свойство кнопки (надпись на кнопке)
«»»
# пользовательский класс MyBox
# на основе базового класса BoxLayout
class MyBox (BoxLayout):
…… pass
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этом программном коде на языке Python создан пользовательский класс MyBox на основе базового класса BoxLayout. При этом нужно явно выполнить импорт базового класса BoxLayout:
from kivy.uix.boxlayout import BoxLayout
После запуска приложения получим следующий результат (рис.2.2).

Рис. 2.2. Результаты выполнения приложения из модуля K_May_Class2.py
Однако есть более простой способ создания пользовательского класса непосредственно в коде на языке KV. Для этого используется следующая конструкция:
<Имя_пользовательского_класса@Имя_базового_класса>
Проверим это на простом примере. Создадим файл с именем K_May_Class3.py и напишем в нем следующий код (листинг 2.3).
Листинг 2.3. Пример использования пользовательского класса (модуль K_My_Class3.py)
# модуль K_May_Class3.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
# пользовательский класс MyBox
# на основе базового класса BoxLayout
<MyBox@BoxLayout>
MyBox: # контейнер (пользовательский класс)
…… Button: # кнопка (класс Button)
…… … … text: «Кнопка 3» # свойство кнопки (надпись на кнопке)
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этом программном коде пользовательский класс MyBox на основе базового класса BoxLayout создан непосредственно в коде на KV:
<MyBox@BoxLayout>
При этом не нужно явно выполнить импорт базового класса BoxLayout, и не нежно объявлять пользовательский класс в разделе программы на Python. При этом сам программный код получается компактным и более понятным.
Примечание.
В этом случае строка, в которой сформирован пользовательский класс, должна находиться между символами <…>.
После запуска приложения получим следующий результат (рис.2.3).

Рис. 2.3. Результаты выполнения приложения из модуля K_May_Class3.py
2.2.2. Динамические классы
Пользовательский класс в Kivy еще называют динамическим классом. Динамический класс создается на основе базового класса, при этом для него можно сразу определить свой набор свойств. Например, в контейнере BoxLayout имеется три кнопки, для которых заданы идентичные свойства:
BoxLayout:
…… Button:
…… … … text: «Кнопка 1»
…… … … pos_hint: {’center_x’:.5, ’center_y’:.6}
…… … … font_size: ’25sp’
…… … … markup: True
…… Button:
…… … … text: " Кнопка 2»
…… … … pos_hint: {’center_x’:.5, ’center_y’:.6}
…… … … font_size: ’25sp’
…… … … markup: True
…… Button:
…… … … text: " Кнопка 3»
…… … … pos_hint: {’center_x’:.5, ’center_y’:.6}
…… … … font_size: ’25sp’
…… … … markup: True
Для того чтобы не повторять многократно задание одних и тех же свойств каждому элементу, можно сформировать динамический класс и в нем один раз задать этот набор свойств:
<MyButton@Button>:
…… pos_hint: {’center_x’:.5, ’center_y’:.6}
…… font_size: ’25sp’
…… markup: True
BoxLayout:
…… MyButton:
…… … … text: " Кнопка 1»
…… MyButton:
…… … … text: " Кнопка 2»
…… MyButton:
…… … … text: " Кнопка 3»
Не вдаваясь в смысл этих свойств, проверим это на простом примере. Создадим файл с именем K_May_Class4.py и напишем в нем следующий код (листинг 2.4).
Листинг 2.4. Пример использования динамического класса (модуль K_My_Class4.py)
# модуль K_May_Class4.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
<MyButton@Button>:
…… font_size: ’25sp’
…… pos_hint: {’center_x’:.5, ’center_y’:.6}
…… markup: True
BoxLayout:
…… orientation: «vertical»
…… MyButton:
…… … … text: " Кнопка 1»
…… MyButton:
…… … … text: " Кнопка 2»
….. MyButton:
…… … … text: " Кнопка 3»
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этом программном коде создан динамический класс MyButton на основе базового класса Button. Для класса MyButton один раз заданы три свойства. Затем в контейнер BoxLayout, помещаются три кнопки MyButton, для которых задается всего одно свойство – text. Все остальные свойства этих кнопок будут наследованы от динамического класса MyButton@Button. Таким образом, программный код упрощается и сокращается количество строк. После запуска приложения получим следующий результат (рис.2.4).

Рис. 2.4. Результаты выполнения приложения из модуля K_May_Class3.py
2.2.3. Зарезервированные слова и выражения в языке KV
В языке KV существует специальный синтаксис для задания значений переменным и свойствам. На Python для присвоения значений переменным используется знак «=», то есть применяется такая конструкция: name = value. На языке KV для задания значений свойствам виджетов используется знак двоеточия «:», например, name: value. В предыдущих примерах мы уже неоднократно встречались с такой конструкцией, например:
Button:
…… text: «Кнопка 1»
На Python импорт (подключение) внешних модулей выглядит следующим образом:
import numpy as np
На языке KV этот код будет выглядеть так:
#:import np numpy
В языке KV имеется три зарезервированных ключевых слова, обозначающих отношение последующего содержимого к тому или иному элементу приложения:
– app: – (приложение) позволяет обратиться к элементам приложения (например, из кода на KV можно обратиться к функциям, которые находится в разделе приложения, написанного на Python);
– root: (корень) позволяет обратиться к корневому виджету;
– self: (сам) позволяет обратиться к себе, и получить от виджета (от себя) свои же параметры;
– args – (аргументы) позволяет указать аргументы при обращении к функциям;
– ids – (идентификаторы) позволяет обратиться к параметрам виджета через его идентификатор.
Ключевое слово self. Ключевое слово self ссылается на «текущий экземпляр виджета». С его помощью можно, например, получить значения свойств текущего виджета. Рассмотрим это на простейшем примере. Создадим файл с именем Button_Self.py и напишем в нем следующий код (листинг 2.5).
Листинг 2.5. Демонстрация использования ключевого слова self (модуль Button_Self.py)
# Модуль Button_Stlf.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
Button
…… text: «Состояние кнопки – %s»% self.state
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Обычно свойству кнопки text присваивается значение типа: «Кнопка», «Подтвердить», «OK», «Да», «Нет» и т. п. Здесь же свойству кнопки text, через префикс self присвоено значение ее же свойства – состояние кнопки (self.state). Получается, что кнопка сделала запрос сама к себе. После запуска приложения получим следующий результат (рис.2.5).

Рис. 2.5. Результаты выполнения приложения из модуля Button_State.py
Как видно из данного рисунка, после изменения состояния кнопка от себя получила значение своего же свойства.
Ключевое слово root. Ключевое слово root (корень) позволяет получить ссылку на параметры корневого виджета. Рассмотрим это на простейшем примере. Создадим файл с именем Button_Root.py и напишем в нем следующий код (листинг 2.6).
Листинг 2.6. Демонстрация использования ключевого слова root (модуль Button_Root.py)
# Модуль Button_Root.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
BoxLayout:
…… orientation: ’vertical’
…… Button:
…… … …text: root. orientation
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Здесь создан корневой виджет BoxLayout и его свойству orientation задано значение – «vertical». Затем в корневой виджет вложен элемент Button (кнопка). Свойству кнопки text, через префикс root присвоено значение свойства корневого виджета – orientation (root. orientation). Получается, что кнопка сделала запрос к свойству корневого виджета. После запуска приложения получим следующий результат (рис.2.6).

Рис. 2.6. Результаты выполнения приложения из модуля Button_Root.py
Как видно из данного рисунка, на кнопке отобразился текст, который соответствует значению свойства корневого виджета.
Ключевое слово app. Это ключевое слово позволяет обратиться к элементу, который относится к приложению. Это эквивалентно вызову функции, которая находится в коде приложения, написанного на Python. Рассмотрим это на простейшем примере. Создадим файл с именем Button_App.py и напишем в нем следующий код (листинг 2.7).
Листинг 2.7. Демонстрация использования ключевого слова app (модуль Button_App.py)
# Модуль Button_App.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
BoxLayout:
…… orientation: ’vertical’
…… Button:
…… … … text: «Кнопка 1»
…… … … on_press: app.press_button (self. text)
…… Label:
…… … … text: app.name
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
def press_button (self, instance):
…… print («Вы нажали на кнопку!»)
…… print (instance)
MainApp().run ()
Примечание.
В этом модуле используется виджет BoxLayout. Более подробно с особенностями этого виджета можно ознакомиться в соответствующем разделе книги.
В этом модуле создан корневой виджет BoxLayout. Затем в корневой виджет вложено два элемента – Button (кнопка) и Label (метка). Событие нажатия кнопки (on_press), будет обработано функцией press_button. Эта функция находится в приложении Main, поэтому перед именем функции стоит префикс app – app.press_button (self. text). То есть в данной строке указано, что мы через префикс app обращаемся к приложению Main, в частности к функции press_button, и передаем в эту функцию свойство text данной кнопки (self. text).
Метка Label имеет свойство text. Этому свойству через префикс app присваивается имя приложения (Main).
Получается, что с использованием префикса app кнопка обратилась к функции приложения и передала ему свое свойство, а метка Label получила значение своего свойства из приложения Main. После запуска данного модуля получим следующий результат (рис.2.7).

Рис. 2.7. Результаты выполнения приложения из модуля Button_App.py
Как видно из данного рисунка, метка Label показала имя приложения (main), а функция обработки события нажатия на кнопку выдала свойство text этой кнопки – «Кнопка 1».
Ключевое слово args. Это ключевое слово используется при обращении к функциям обратно вызова для передачи им аргументов. Это относится к аргументам, переданным обратному вызову. Рассмотрим это на простейшем примере. Создадим файл с именем Button_Args.py и напишем в нем следующий код (листинг 2.8).
Листинг 2.8. Демонстрация использования ключевого слова args (модуль Button_Args.py)
# Модуль Button_Args.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
BoxLayout:
…… orientation: ’vertical’
…… Button:
…… … … text: «Кнопка 1»
…… … … on_press: app.press_button (*args)
…… TextInput:
…… … … on_focus: self.insert_text («Фокус» if args [1] else «Нет»)
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def press_button (self, instance):
…… … … print («Вы нажали на кнопку!»)
…… … … print (instance)
MainApp().run ()
В этом модуле создан корневой виджет BoxLayout. Затем в корневой виджет вложено два элемента – Button (кнопка) и TextInput (поле для ввода текста). Событие нажатия кнопки (on_press), будет обработано функцией press_button (*args). В скобках указаны аргументы, которые будут переданы в данную функцию (звездочка * говорит о том, что будут переданы все аргументы от текущего виджета).
У виджета TextInput определено событие получения фокуса (on_focus). Для обработки этого события будет использоваться функция insert_text (вставить текст):
self.insert_text («Фокус" if args [1] else «Нет»)
Какой текст будет вставлен, зависит от значения args [1]. Если тестовое поле получит фокус, то в поле ввода будет вставлен текст «Фокус», если поле для ввода текста потеряет фокус, то будет вставлено слово «Нет». После запуска данного модуля получим следующий результат (рис.2.8).

Рис. 2.8. Результаты выполнения приложения из модуля Button_Args.py
Как видно из данного рисунка, в поле для ввода текста TextInput показаны результаты обработки события получения и потери фокуса, а в окне терминал показаны результаты обработки события нажатия на кнопку. В обоих случаях для передачи аргументов использовалось ключевое слово args.
Ключевое слово ids. Ключевые слова ids (идентификаторы) и id (идентификатор) используются для идентификации виджетов. С использованием ключевого слова id можно любому виджету назначить уникальное имя (идентификатор). Это имя можно использовать для ссылок на виджет, то есть обратиться к нему в коде на языке KV.
Рассмотрим следующий код:
Button:
…… id: but1
…… text: «Кнопка 1»
Label:
…… text: but1.text
В этом коде создано два элемента интерфейса: виджет Button (кнопка), и виджет Label (метка). Кнопке через ключевое слово id присвоено уникальное имя – but1, через которое теперь можно обращаться к свойствам данного элемента. Свойству text метки Label присвоено значение «but1.text». То есть метка обратилась к кнопке bat1 и получила от кнопки значение его свойства text. В итоге метка покажет на экране текст «Кнопка 1».
Рассмотрим это на простейшем примере. Создадим файл с именем Button_Id.py и напишем в нем следующий код (листинг 2.9).
Листинг 2.9. Демонстрация использования ключевого слова id (модуль Button_Id.py)
# Модуль Button_Id.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
BoxLayout:
…… orientation: ’vertical’
…… Button:
…… … … id: bt1
…… … … text: «Кнопка 1»
…… … … on_press: lb1.text = bt1.text
…… Button:
…… … … id: bt2
…… … … text: «Кнопка 2»
…… … … on_press: lb1.text = bt2.text
…… Label:
…… … … id: lb1
…… … … text: «Метка»
…… … … on_touch_down: self. text = «Метка»
«»»
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этом модуле создан корневой виджет BoxLayout. Затем в корневой виджет вложено три элемента: две кнопки Button, и метка Label. Кнопки имеют идентификаторы «bt1» и «bt2», а метка идентификатор «lb1». При касании кнопки bt1 (событие on_press) свойству метки text будет присвоено значение аналогичного свойства кнопки bt2, что запрограммировано в выражении:
on_press: lb1.text = bt1.text xt
При касании кнопки bt2 (событие on_press) свойству метки text будет присвоено значение аналогичного свойства кнопки bt2, что запрограммировано в выражении:
on_press: lb1.text = bt2.text
При касании метки lb1 (событие on_touch_down) свойству метки text будет присвоено значение «Метка», что запрограммировано в выражении:
on_touch_down: self. text = «Метка»
В итоге после касания всех элементов содержание метки будет меняться. После запуска приложения получим следующий результат (рис.2.9).

Рис. 2.9. Результаты выполнения приложения из модуля Button_Id.py
Как видно из данного рисунка, после касания элементов интерфейса меняется текст у метки Label, то есть сработала ссылка одного виджета на другой через их идентификаторы.
С использованием ключевого слова ids можно из кода на Python обратиться к виджету, который создан в разделе программы в коде на KV. Рассмотрим это на простейшем примере. Создадим файл с именем Button_Ids.py и напишем в нем следующий код (листинг 2.10).
Листинг 2.10. Демонстрация использования ключевого слова ids (модуль Button_Ids.py)
# Модуль Button_Ids.py
from kivy. app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
KV = «»»
box:
…… Button:
…… … … text: ' Кнопка»
…… … … on_press: root.result («Нажата кнопка»)
…… Label:
…… … … id: itog
«»»
class box (BoxLayout):
…… def result (self, entry_text):
…… … … self.ids [«itog»].text = entry_text
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Здесь во фрагменте модуля, написанного на Python, создан пользовательский класс box на основе базового класса BoxLayout. Это по своей сути контейнер, в который на языке KV вложено два элемента: кнопка Button и метка Label, которая имеет имя (идентификатор) «itog». При касании кнопки возникает событие (on_press). Это событие обрабатывается в корневом виджете root, в функции result, куда передается текст «Нажата кнопка». В функции def result этот текст принимается в параметр entry_text. А вот в следующей строке как раз происходит использование ключевого слова ids:
self.ids [«itog»].text = entry_text
Эта строка говорит о том, что свойству text элемент корневого виджета с именем (идентификатором) [«itog»] нужно присвоить значение параметра entry_text. Поскольку данному параметру будет передано значение «Нажата кнопка», то этот текст отобразится на экране. После запуска приложения получим следующий результат (рис.2.10).

Рис. 2.10. Результаты выполнения приложения из модуля Button_Ids.py
Как видно из данного рисунка, текст «Нажата кнопка», сначала был передан из фрагмента кода на KV во фрагмент кода на Python, а затем возвращен обратно. Для этого были использованы ключевые слова ids и id.
Рассмотрим использование идентификаторов виджетов для обмена параметрами между фрагментами кода на языке KV и на Python, на развернутом примере простейшего калькулятора. Для этого создадим файл с именем Simpl_Calc.py и напишем в нем следующий код (листинг 2.11).
Листинг 2.11. Демонстрация использования ключевых слов ids и id (модуль Simpl_Calc.py)
# Модуль Simpl_Calc.py
from kivy. app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
KV = «»»
box:
…… #корневой виджет
…… id: root_widget
…… orientation: ’vertical’
…… #поле для ввода исходных данных
…… TextInput:
…… …… id: entry
…… …… font_size: 32
…… …… multiline: False
…… #кнопка для выполнения расчета
…… Button:
…… …… text: «=»
…… …… font_size: 64
…… …… #on_press: root.result (entry. text)
…… …… on_press: root_widget.result (entry. text)
…… #поле для показа результатов расчета
…… Label:
…… …… id: itog
…… …… text: «Итого»
…… …… font_size: 64
«»»
# класс, задающий корневой виджет
class box (BoxLayout):
…… # Функция подсчета результата
…… def result (self, entry_text):
…… …… if entry_text:
…… …… …… try:
…… …… …… …… # Формула для расчета результатов
…… …… …… …… result = str (eval (entry_text))
…… …… …… …… self.ids [«itog»].text = result
…… …… …… except Exception:
…… …… …… …… # если введено не число
…… …… …… …… self.ids [«itog»].text = «Ошибка»
# базовый класс приложения
class MainApp (App):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этом модуле создан базовый класс приложения MainApp, который обеспечивает запуск приложения, и пользовательский класс box на основе базового класса BoxLayout (контейнер – коробка). В этом классе создана функция def result, в которой происходят вычисления. В коде на языке KV созданы следующие элементы интерфейса:
– корневой виджет box (id: root_widget);
– поле для ввода текста TextInput (id: entry);
– кнопка для запуска процесса выполнения расчетов (id: itog);
– метка Label для вывода на экран результатов расчета.
С использованием имен-идентификаторов происходит обмен данными межу фрагментами кода на языке KV и на Python. После запуска приложения получим следующий результат (рис.2.11).

Рис. 2.11. Результаты выполнения приложения из модуля Simpl_Calc.py
Как видно из данного рисунка, мини – калькулятор работает корректно. При этом интерфейс приложения создан на языке KV, а расчеты выполняются в коде на языке Python.
Для ввода данных в текстовое поле необходимо использовать клавиатуру. При этом Kivy определит, на каком устройстве запущено приложение: на настольном компьютере, или на мобильном устройстве. В зависимости от этого будут задействованы разные клавиатуры:
– если приложение запущено на настольном компьютере, то будет использоваться клавиатура этого компьютера;
– если приложение запущено на мобильном устройстве, то будет использоваться всплывающая клавиатура этого устройства.
Если скомпилировать приведенное выше приложение и запустить его на смартфоне, то получим следующий результат (рис.2.12).

Рис. 2.12. Результаты выполнения приложения из модуля Simpl_Calc.py на мобильном устройстве
Как видно из данного рисунка, при загрузке приложения клавиатура на экране отсутствует. Как только поле для ввода текста получает фокус (касание поля), то появляется клавиатура. На этой клавиатуре можно набирать алфавитно-цифровую информацию и переключать язык ввода. При нажатии на кнопку со знаком «=» клавиатура исчезает, и становятся видны результаты расчета.
В коде на языке Kivy допускается использования некоторых операторов и выражений Python. При этом выражение может занимать только одну строку и должно возвращать значение. Рассмотрим это на простом примере. Создадим файл с именем Button_If.py и напишем в нем следующий код (листинг 2.12).
Листинг 2.12. Демонстрация использования выражений в KV (модуль Button_If.py)
# Модуль Button_If.py
from kivy. app import App
from kivy.lang import Builder
KV = «»»
BoxLayout:
…… orientation: ’vertical’
…… Button:
…… …… id: bt1
…… …… text: «Кнопка 1»
…… Label:
…… …… text: «Отпущена» if bt1.state == ’normal’ else «Нажата»
«»»
class MainApp (App):
……def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этом модуле создан корневой виджет BoxLayout. Затем в корневой виджет вложено два элемента: кнопка Button, и метка Label. Кнопка имеет идентификатор «id: bt1». Свойству метки text присвоено выражение:
text: «Кнопка отпущена» if bt1.state == ’normal’ else «Кнопка нажата»
Это выражение говорит о том, что, если кнопка будет находиться в нормальном состоянии, то метка покажет текст «Кнопка отпущена». А если кнопка будет находиться в нажатом состоянии, то метка покажет текст «Кнопка Нажата». После запуска приложения получим следующий результат (рис.2.13).
