Читать книгу Разработка кроссплатформенных мобильных и настольных приложений на Python. Практическое пособие - Анатолий Постолит - Страница 24

Глава 2. Фреймоворк Kivy, язык KV и виджеты, как основа пользовательского интерфейса
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).


Рис. 2.13. Результаты выполнения приложения из модуля Button_If.py


Итак, мы познакомились с некоторыми особенностями языка KV, с тем, как можно создавать и использовать классы на языке KV и идентифицировать виджеты. Теперь можно более детально познакомиться со структурой приложений на Kivy, а затем перейти к базовым элементам, на основе которых строится пользовательский интерфейс – к виджетам.

Разработка кроссплатформенных мобильных и настольных приложений на Python. Практическое пособие

Подняться наверх