Глава 5. Компоненты пользовательского интерфейса KivyMD
В предыдущей главе мы познакомились со структурой приложений на Kivy, с простейшими виджетами Label (метка) и Buttun (кнопка), с виджетами позиционирования элементов интерфейса в окне приложения, с возможностями обработки событий и работы с цветом. Для разработки пользовательского интерфейса в фреймворке Kivy имеется достаточно большой набор виджетов. Однако в процессе развития данного фреймворка он был дополнен библиотекой KivyMD, в которой был реализован гораздо больший набор виджетов с достаточно привлекательным интерфейсом.
KivyMD поддерживает множество компонентов, которые делают приложения интерактивными. Можно добавлять текст, изображения, значки, раскрывающиеся списки, панели навигации, таблицы и буквально все, что возможно реализовать в приложениях для Android. Разработчики этой библиотеки постоянно добавляют новые функции. Программистам гораздо проще работать с данной библиотекой, поскольку ее применение обеспечивает сокращение программного кода. С учетом этого в данной главе будут рассмотрены компоненты для создания пользовательского интерфейса именно из библиотеки KivyMD. Перечень этих компонент в алфавитном порядке представлен в табл.5.1.
Таблица 5.1
Компоненты библиотеки KivyMD для создания пользовательского интерфейса
В этом же порядке в следующих разделах приведено подробное описание этих компонент и примеры использования
5.1. MDBackdrop — двухслойная панель со сменными слоями
Компонента Backdrop позволяет создать окно приложения, у которого имеется два слоя (рис.5.1).
Рис. 5.1. Структура слоев (поверхностей) компоненты Backdrop.py
Backdrop состоит из двух поверхностей (слоев): заднего слоя и переднего слоя. Задний слой отображает контекст или действия, которые управляют содержимым переднего слоя. Backdrop обеспечивает быструю смену слоев при прикосновении к экрану. При первой загрузки окна приложения с элементом Backdrop пользователь видит передний слой с неким контентом, и верхнюю часть заднего слоя с элементами управления. По умолчанию передний слой имеет белый цвет, задний синий цвет.
Передний слой. Передний слой может содержать различные компоненты, такие как:
— Текстовые списки
— Списки изображений
— Карточки
— Текст
Если эти компоненты не помещаются на экран, то обеспечивается их скроллинг (прокрутка). Подзаголовок можно зафиксировать на месте, в то время как содержимое под ним на переднем слое будет прокручиваться независимо от заголовка.
Задний слой. Когда раскрывается задний слой, то он заполняет все окно приложения. Он содержит полезный контент, относящийся к переднему слою. Задний слой может содержать компоненты для навигации, фильтрации, или изменения значений параметров, такие как:
— навигация;
— ползунки для изменения параметров (Steppers);
— текстовые поля;
— элементы управления выбором.
Выбор той или иной компоненты повлияет на содержимое переднего слоя. Ниже приведены шаги, необходимые для создания Backdrop:
— Создать приложение путем импорта класса MDApp модуля kivymd.
— Создать экран с использованием класса MDScreen.
— Создать панель Backdrop с использованием класса MDBackdrop.
Мы реализуем пример демонстрации работы MDBackdrop с использованием языка KV и компоненты Builder в рамках одного программного модуля. Создадим файл с именем Backdrop.py внесем в него следующий код (листинг 5.1).
Листинг 5.1. Демонстрации работы MDBackdrop (модуль Backdrop.py)
# Модуль Backdrop.py
from kivymd. app import MDApp
from kivy.lang import Builder
KV = «»»
MDScreen:
…… MDBackdrop: # общие параметры backdrop
…… …… id: backdrop
…… …… header: True
…… …… title: «Заголовок заднего слоя»
…… …… header_text: «Заголовок переднего слоя»
…… …… right_action_items: [[’login’,lambda x: print («Кнопка Вход»)],
………… …… …… …… …… …… [’apple’, lambda x: print («Кнопка Apple»)]]
…… …… #padding: [20] # Отступ подзаголовка от верхнего края
…… …… #radius_right: «0dp»
…… …… #radius_left: «0dp»
…… …… #close_icon: ’account’
…… …… # параметры элементов заднего слоя
…… …… MDBackdropBackLayer:
…… …… … … MDFlatButton:
…… …… … … … … text: «Кнопка заднего слоя»
…… …… …… … … pos_hint: {«center_x»:. 5,«center_y»:. 15}
…… …… …… … … on_press: app.callback1 ()
…… …… # параметры элементов переднего слоя
…… …… MDBackdropFrontLayer:
…… …… …… MDFlatButton:
…… … … …… …… text: «Кнопка переднего слоя»
…… … … …… …… on_press: app.callback2 ()
«»»
class Myapp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback1 (self):
…… …… # self.root.ids.backdrop.close ()
…… …… print («Нажата кнопка на заднем слое»)
…… def callback2 (self):
…… …… print («Нажата кнопка на переднем слое»)
Myapp().run ()
Рассмотрим компоненты и их параметры, которые используемых в этой программе.
Был выполнен импорт модулей базовых классов библиотеки KivyMD:
— MDApp — приложение;
— Builder — загрузчик программного кода на языке KV.
В строковую переменную KV загрузили два элемента: MDScreen (экран) и MDBackdrop (двухслойная панель со сменными слоями).
Для элемента MDBackdrop заданы значения следующим общим свойствам:
— title: — текст заголовка заднего слоя;
— header_text: — текст заголовка переднего слоя;
— right_action_items: — определение активных элементов в строке заголовка.
Свойство «right_action_items:» служит для размещения в правой части строки заголовка активных элементов, при нажатии на которые можно выполнять некоторые действия. В этом свойстве заданы две иконки «login» и «apple», при нажатии на которые будут выполнены команды, указанные в lambda функциях — «lambda x:».
Здесь имеются следующие закомментированные строки, сняв комментарии с которых можно получить следующие результаты:
— padding: [20] — задать отступ заголовка переднего слоя от верхнего края;
— radius_right: «0dp» — убрать округленность правого угла окна переднего слоя;
— radius_left: «0dp» — убрать округленность левого угла окна переднего слоя;
— close_icon: ’account’ — задать другую иконку (вместо «X») для свертывания переднего слоя.
На задний слой (MDBackdropBackLayer:) помещена кнопка (MDFlatButton:), для которой заданы значения следующих свойств:
— text: — надпись на кнопке;
— pos_hint: — позиция кнопки в окне;
— on_press: app.callback1 () — функция, которой будет передано управление при возникновения события нажатия кнопки.
На передний слой (MDBackdropFrontLayer) помещена кнопка (MDFlatButton), для которой заданы значения следующих свойств:
— text: — надпись на кнопке;
— on_press: app.callback2 () — функция, которой будет передано управление при возникновения события нажатия кнопки.
Поскольку не была задана позиция кнопки то, по умолчанию, она будет размещена в нижнем левом углу переднего слоя
В базовом классе Myapp заданы три функции: build, callback1 и callback2. Первая функция позволяет загрузить программный код на языке KV из строковой переменной KV и запустить его на выполнение, вторые две обрабатывают события нажатия кнопок.
После запуска данного приложения получим следующий результат (рис.5.2).
Рис. 5.2. Результат выполнения приложения из модуля Backdrop.py
Как видно из данного рисунка, по умолчанию окно переднего слоя имеет белый фон, заднего слоя синий. При нажатии на иконку в левом углу заднего слоя передний слой будет свернут и появятся все элементы, расположенные на заднем слое. При нажатии иконки «Х» в левом верхнем углу заднего слоя, он снова будет скрыт передним слоем. При нажатии на иконки в правом верхнем углу заднего слоя отработают связанные с ними функции. Поскольку на переднем и заднем слое имеется только по одному элементу, то скроллинг экрана не выполняется.
5.2. MDBanner — элемент (значок) со связанным с ним действием
Banner это хорошо заметный элемент интерфейса (текст или изображение), который отображает заметное сообщение и связанные с ним необязательные действия.
Баннер отображается в верхней части экрана, чуть ниже верхней панели — Toolbar (Top). Пользователь может либо игнорировать баннер, либо взаимодействовать с ним. В текущем окне должен отображаться только один баннер
Мы реализуем пример демонстрации работы MDBanner с использованием языка KV и компоненты Factory в рамках одного программного модуля.
Создадим файл с именем Banner.py внесем в него следующий код (листинг 5.2).
Листинг 5.2. Демонстрации работы MDBanner (модуль Banner.py)
# модуль Banner.py
from kivy.lang import Builder
from kivy. factory import Factory
from kivymd. app import MDApp
Builder. load_string (»»»
<ExampleBanner@Screen>
…… MDBanner:
…… …… id: banner
…… …… text: [«Это однострочный баннер»]
…… …… over_widget: screen
…… …… vertical_pad: toolbar. height
…… MDToolbar:
…… …… id: toolbar
…… …… title: «Компонента Banner»
…… …… elevation: 10
…… …… pos_hint: {’top’: 1}
…… BoxLayout:
…… …… id: screen
…… …… orientation: «vertical»
…… …… size_hint_y: None
…… …… height: Window. height — toolbar. height
…… …… OneLineListItem:
…… …… …… text: «Отобразить баннер»
…… …… …… on_release: banner.show ()
…… …… Widget:
««»)
class Myapp (MDApp):
…… def build (self):
…… …… return Factory. ExampleBanner ()
Myapp().run ()
После запуска данного приложения получим следующий результат (рис.5.3).
Рис. 5.3. Результат выполнения приложения из модуля Banner.py
Как видно из данного рисунка, при нажатии на текст «Открыть баннер» он появляется под верхней строкой (компонента MDToolbar). После выполнения любых действий, например, касание экрана, баннер скроется.
5.3. MDBottom Navigation нижняя панель с элементами навигации по приложению
Нижняя панель навигации позволяет перемещаться между различными разделами приложения.
Нижняя панель навигации находится внизу экрана и отображает от трех до пяти элементов. Каждый элемент представлен иконкой (значком) и дополнительной текстовой меткой. При касании нижнего элемента навигации пользователь попадает в раздел приложения, связанный с этим значком.
Создадим файл Bottom_Navi.py внесем в него следующий код (листинг 5.3).
Листинг 5.3. Демонстрации работы MDBottom_Navi (модуль Bottom_Navi.py)
# модуль Bottom_Navi.py
from kivymd. app import MDApp
from kivy.lang import Builder
KV = «»»
BoxLayout:
…… orientation:’vertical’
…… MDToolbar:
…… …… title: «Пример Bottom Navigation’
…… …… MDBottomNavigation:
…… …… …… panel_color: 255/255, 255/255, 204/255, 1
…… …… …… #panel_color: 0, 0, 1, 1
…… …… …… MDBottomNavigationItem:
…… …… …… …… name: ’screen 1»
…… …… …… …… text: «Python’
…… …… …… …… icon: ’language-python’
…… …… …… …… MDLabel:
…… … … …… …… …… text: «Вкладка программирование на Python’
…… … … …… …… …… halign: ’center’
…… …… …… MDBottomNavigationItem:
…… …… …… …… name: ’screen 2»
…… …… …… …… text: «C++»
…… …… …… …… icon: ’language-cpp’
…… …… …… …… MDLabel:
…… … … …… …… …… text: «Вкладка программирование на C++»
…… … … …… …… …… halign: ’center’
…… …… …… MDBottomNavigationItem:
…… …… …… …… name: ’screen 3»
…… …… …… …… text: «Java’
…… …… …… …… icon: ’language-javascript’
…… …… …… …… MDLabel:
…… …… …… …… …… text: «Вкладка программирование на Java Script’
…… …… …… …… …… halign: ’center’
«»»
class Myapp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
Myapp().run ()
После запуска данного приложения получим следующий результат (рис.5.4).
Рис. 5.4. Результат выполнения приложения из модуля Bottom_Navi
5.4. Bottom Sheet (MDListBottomSheet) нижний лист с элементами приложения
Bottom Sheet — это поверхность (часть экрана), содержащая дополнительный контент, который прикреплен к нижней части экрана. Доступны два класса MDListBottomSheet и MDGridtBottomSheet для создания диалоговых окон в нижних листах.
Создадим файл BottomSheet_List.py внесем в него следующий код (листинг 5.4).
Листинг 5.4. Демонстрации работы BottomSheets (модуль BottomSheet_List.py)
# модуль BottomSheet_List.py
from kivy.lang import Builder
from kivymd.toast import toast
from kivymd.uix.bottomsheet import MDListBottomSheet
from kivymd. app import MDApp
KV = «»»
Screen:
…… MDToolbar:
…… … … title: «Пример BottomSheet»
…… … … pos_hint: {«top»: 1}
…… … … elevation: 10
…… MDRaisedButton:
…… … … text: «Открыть в виде списка»
…… … … on_release: app.show_example_list_bottom_sheet ()
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def callback_for_menu_items (self, *args):
…… … … toast (args [0])
…… def show_example_list_bottom_sheet (self):
…… … … bottom_sheet_menu = MDListBottomSheet ()
…… … … for i in range (1, 11):
…… … … … … bottom_sheet_menu.add_item (f"Элемент списка {i}»,
…… … … … … lambda x, y=i: self.callback_for_menu_items (
…… … … … … … … f«Выбран элемент списка {y}»),)
…… … … bottom_sheet_menu. open ()
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.5).
Рис. 5.5. Результат выполнения приложения из модуля BottomSheet_List.py
Как видно из данного рисунка, при нажатии на кнопку «Открыть в виде списка» элементы списка появляются в нижней части экрана. После выбора одного из элементов списка он закрывается, и вместо него появляется временный баннер, который через некоторое время автоматически скроется.
Метод add_item класса MDListBottomSheet принимает следующие аргументы —
add_item (text, callback, icon_src), где:
— text — текст элемента;
— callback — функция, которая будет вызываться при нажатии на элемент;
— icon_src необязательный аргумент — иконка (значок) слева от элемента.
Пример списка с иконками приведен на рис.5.6.
Рис. 5.6 Элементы списка BottomSheet с иконками
Теперь создадим файл BottomSheet_Grid.py внесем в него следующий код (листинг 5.5).
Листинг 5.5. Демонстрации работы BottomSheets (модуль BottomSheet_Grid.py)
# модуль BottomSheet_Grid.py
from kivy.lang import Builder
from kivymd.toast import toast
from kivymd.uix.bottomsheet import MDGridBottomSheet
from kivymd. app import MDApp
KV = «»»
Screen:
…… MDToolbar:
…… …… title: «Пример BottomSheet’
…… …… pos_hint: {«top»: 1}
…… …… elevation: 10
…… MDRaisedButton:
…… …… text: «Открыть в виде таблицы»
…… …… on_release: app.show_example_grid_bottom_sheet ()
…… …… pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback_for_menu_items (self, *args):
…… …… toast (args [0])
…… def show_example_grid_bottom_sheet (self):
…… …… bottom_sheet_menu = MDGridBottomSheet ()
…… …… data = {«Facebook»: «facebook», «YouTube»: «youtube»,
…… …… …… «Twitter»: «twitter», «Cloud»: «cloud-upload»,
…… …… …… «Камера»: «camera», }
…… …… for item in data.items ():
…… …… …… bottom_sheet_menu.add_item (item [0],
…… …… …… lambda x, y=item [0]: self.callback_for_menu_items (y),
…… …… …… …… icon_src=item [1],)
…… …… …… bottom_sheet_menu. open ()
MainApp().run ()
Метод add_item класса MDListBottomGrid принимает следующие аргументы —
add_item (text, callback, icon_src), где:
— text — текст элемента;
— callback — функция, которая будет вызываться при нажатии на элемент;
— icon_src необязательный аргумент — иконка (значок) слева от элемента.
После запуска данного приложения получим следующий результат (рис.5.7).
Рис. 5.7. Результат выполнения приложения из модуля BottomSheet_Grid.py
Как видно из данного рисунка, при нажатии на кнопку «Открыть в виде таблицы» элементы таблицы появляются в нижней части экрана. После выбора одного из элементов таблица закрывается, и вместо нее появляется временный баннер, который через некоторое время автоматически скроется.
5.5. Button — набор компонент для активации действий пользователя
Button или кнопка, это элемент интерфейса, при воздействии на который со стороны пользователя выполняются различные запрограммированные действия. В библиотеке KivyMD имеется несколько классов, позволяющих создавать кнопки:
— MDIconButton;
— MDFloatingActionButton;
— MDFlatButton;
— MDRaisedButton;
— MDRectangleFlatButton;
— MDRectangleFlatIconButton;
— MDRoundFlatButton;
— MDRoundFlatIconButton;
— MDFillRoundFlatButton.
— MDFillRoundFlatIconButton;
— MDTextButton;
— MDFloatingActionButtonSpeedDial;
Рассмотрим возможности каждого из этих классов на конкретных примерах.
5.5.1. MDIconButton — класс для создания кнопок в виде иконок
Класс MDIconButton позволяет создать кнопки различного размера в виде иконок или изображений. Рассмотрим это на примере.
Создадим файл IconButton.py и напишем в нем следующий код (листинг 5.6).
Листинг 5.6. Демонстрации работы MDIconButton (модуль IconButton.py)
# модуль IconButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDIconButton:
…… … … #icon: «language-python»
…… … … #icon: "./Images/icon.png»
…… … … #user_font_size: «64sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: app.theme_cls.primary_color
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— #icon:- имя иконки из доступных в Kivy («language-python»);
— #icon:-имя иконки из файла с изображением ("./Images/icon.png)»;
— #user_font_size: — размер иконки («64sp»);
— #theme_text_color: цветовая тема иконки («Custom»);
— #text_color: — цвет иконки (app.theme_cls.primary_color);
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5}).
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя эти параметры и меняя их значения можно получить разные варианты этой кнопки. Запуская данное приложение с разными параметрами, получим следующие результаты (рис.5.8).
Рис. 5.8. Результат выполнения приложения из модуля IconButton.py
Если для данной кнопки не задан параметр имя иконки (icon), то по умолчанию будет использоваться иконка в виде черного кружка. Имя иконки можно задать либо из списка возможных иконок фрейморка Kivy, либо из файла пользователя с любым изображением. В данном варианте программы задано положение иконки в центре экрана.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (табл.5.2).
Таблица 5.2.
Влияние параметров кнопок на их внешний вид
Меняя эти свойства можно получить кнопки с разными изображениями, размерами и цветовой гаммой.
5.5.2. MDFloatingActionButton — класс для создания парящих кнопок в виде иконок
Класс MDFloatingActionButton позволяет создать «парящие кнопки в виде иконок. Эти кнопки имеют тень, что создает впечатление, что они парят над основной поверхностью экрана. Создадим файл FloatActButton.py и напишем в нем следующий код (листинг 5.7).
Листинг 5.7. Демонстрации работы MDFloatingActionButton (модуль FloatActButton.py)
# модуль FloatActButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDFloatingActionButton:
…… …… icon: ’microphone’
…… …… elevation: 20
…… …… pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… …… on_press: print («Кнопка нажата»)
…… …… #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— icon:- имя иконки из перечня иконок фреймворка Kivy («microphone»);
— elevation: — размер отбрасываемой тени или высота «парения» (20);
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
При запуске приложения в таком варианте мы получим следующий результат (рис.5.9).
Рис. 5.9. Результат выполнения приложения из модуля FloatActButton.py
Меняя значение свойства elevation (высота поднятия), можно изменять размер тени, которую отбрасывает кнопка
5.5.3. MDFlatButton — класс для создания надписи с функциями кнопки
Класс MDFlatButton позволяет превращать надписи в кнопки. Этот прием используется довольно часто в приложениях, особенно когда экран имеет небольшие размеры. Создадим файл FlatButton.py и напишем в нем следующий код (листинг 5.8).
Листинг 5.8. Демонстрации работы MDFlatButton (модуль FloatButton.py)
# модуль FlatButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDFlatButton:
…… … … text: «КНОПКА»
…… … … #font_size: «20sp»
…… … … #font_name: 'gothic.ttf’
…… … … #theme_text_color: «Custom»
…… … … #text_color: 0, 0, 1, 1
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text: надпись на кнопке («КНОПКА»);
— #font_size: — размер шрифта надписи («20sp»);
— #font_name: — наименования шрифта ('gothic.ttf)»;
— #theme_text_color:- цветовая тема надписи («Custom»);
— #text_color: цвет надписи (0, 0, 1, 1) /
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5}).
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.10).
Рис. 5.10. Результат выполнения приложения из модуля FlatButton.py
Как видно из данного рисунка, кнопка может иметь разные размеры и цвета надписи, но не имеет фона. В момент нажатия на текст вокруг него временно появляется цветной фон в виде кнопки.
Разработчик может использовать свой шрифт, загрузив его в одну из папок приложения, задав путь к этому файлу:
font_name: «path/to/font»
5.5.4. MDRaisedButton — класс для создания выделенной кнопки
Класс MDRaisedButton позволяет создавать традиционные кнопки. Эта кнопка похожа на описанную выше кнопку с надписью, она отличается тем, что для нее можно установить цвет фона. Создадим файл RaisedButton.py и напишем в нем следующий код (листинг 5.9).
Листинг 5.9. Демонстрации работы MDRaisedButton (модуль RaisedButton.py)
# модуль RaisedButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDRaisedButton:
…… … … text: «КНОПКА»
…… … … #md_bg_color: 1, 0, 1, 1
…… … … #font_size: «25sp»
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text: надпись на кнопке («КНОПКА»);
— #md_bg_color: — цвет фона (1, 0, 1, 1);
— #font_size: — размер шрифта надписи («25sp»);
— #theme_text_color:- цветовая тема надписи («Custom»);
— #text_color: цвет надписи (0, 0, 1, 1);
— #font_name: — файл с наименованием шрифта ('gothic.ttf);
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.11).
Рис. 5.11. Результат выполнения приложения из модуля RaisedButton.py
5.5.5. MDRectangleFlatButton — класс для создания текстовой кнопки с рамкой
Класс MDRectangleFlatButton позволяет создавать кнопку с текстом в прямоугольной рамке. Эта кнопка не имеет собственного цвета фона, но при этом можно задавать цвет рамки и цвет текста. Создадим файл RectFlatButton.py и напишем в нем следующий код (листинг 5.10).
Листинг 5.10. Демонстрации работы MDRectangleFlatButton (модуль RectFlatButton.py)
# модуль RectFlatButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDRectangleFlatButton:
…… … … text: «КНОПКА»
…… … … #font_size: «25sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: 1, 0, 0, 1
…… … … #line_color: 0, 0, 1, 0
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text: надпись на кнопке («КНОПКА»);
— #font_size:- размер шрифта надписи («25sp»);
— #theme_text_color: — цветовая тема надписи («Custom»);
— #text_color: — цвет надписи (1, 0, 0, 1);
— #line_color: — цвет рамки (0, 0, 1, 1) /
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5}).
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.12).
Рис. 5.12. Результат выполнения приложения из модуля RectFlatButton.py
5.5.6. MDRectangleFlatIconButton — класс для создания текстовой кнопки с иконкой и рамкой
Класс MDRectangleFlatIconButton позволяет создавать кнопку с текстом в прямоугольной рамке, снабженную иконкой. Эта кнопка не имеет собственного цвета фона, но при этом можно задавать цвет рамки и цвет текста. В отличие от предыдущей кнопки рядом с текстом можно поставить иконку. Создадим файл RectFlatIconButton.py и напишем в нем следующий код (листинг 5.11).
Листинг 5.11. Демонстрации работы MDRectangleFlatIconButton (модуль RectFlatIconButton.py)
# модуль RectFlatIconButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDRectangleFlatIconButton:
…… … … text: «КНОПКА»
…… … … #icon: «language-python»
…… … … #font_size: «25sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: 1, 0, 0, 1
…… … … #line_color: 0, 0, 1, 1
…… … … #line_color: 0, 0, 0, 0
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text:- надпись на кнопке («КНОПКА»);
— #icon: — иконка («language-python»);
— #font_size: — размер шрифта надписи («25sp»);
— #theme_text_color: — цветовая тема надписи («Custom»);
— #text_color:- цвет надписи (1, 0, 0, 1);
— #line_color: — цвет рамки (0, 0, 1, 1);
— #line_color: — обесцветить рамку (0, 0, 0, 0);
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.13).
Рис. 5.13. Результат выполнения приложения из модуля RectFlatIconButton.py
Если для данной кнопки не задан параметр имя иконки (icon), то по умолчанию будет использоваться иконка «android».
5.5.7. MDRoundFlatButton — класс для создания кнопки в виде текста в рамке с округлыми краями
Класс MDRoundFlatButton позволяет создавать кнопку в виде текста в рамке с округлыми краями. Эта кнопка не имеет собственного цвета фона, но при этом можно задавать цвет рамки и цвет текста. Создадим файл RoundFlatButton.py и напишем в нем следующий код (листинг 5.12).
Листинг 5.12. Демонстрации работы MDRoundFlatButton (модуль RoundFlatButton.py)
# модуль RoundFlatButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDRoundFlatButton:
…… … … text: «КНОПКА»
…… … … #font_size: «25sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: 1, 0, 0, 1
…… … … #line_color: 0, 0, 1, 1
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text:- надпись на кнопке («КНОПКА»);
— #font_size: — размер шрифта надписи («25sp»);
— #theme_text_color: — цветовая тема надписи («Custom»);
— #text_color:- цвет надписи (1, 0, 0, 1);
— #line_color: — цвет рамки (0, 0, 1, 1);
— #line_color: — обесцветить рамку (0, 0, 0, 0);
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.14).
Рис. 5.14. Результат выполнения приложения из модуля RectFlatIconButton.py
5.5.8. MDRoundFlatIconButton — класс для создания кнопки в виде текста в рамке с округлыми краями и иконкой
Класс MDRectangleFlatIconButton позволяет создавать кнопку в виде текста в рамке с округлыми краями и иконкой. Эта кнопка не имеет собственного цвета фона, но при этом можно задавать цвет рамки и цвет текста. В отличие от предыдущей кнопки рядом с текстом можно поставить иконку. Создадим файл RoundFlatIconButton.py и напишем в нем следующий код (листинг 5.13).
Листинг 5.13. Демонстрации работы MDRoundFlatIconButton (модуль RoundFlatIconButton.py)
# модуль RoundFlatIconButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDRoundFlatIconButton:
…… … … text: «КНОПКА»
…… … … #icon: «language-python»
…… … … #font_size: «25sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: 1, 0, 0, 1
…… … … #line_color: 0, 0, 1, 1
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text: — надпись на кнопке («КНОПКА»);
— icon: — иконка («language-python»);
— font_size: — размер шрифта надписи («25sp)»;
— theme_text_color: — цветовая тема надписи («Custom»);
— text_color: — цвет надписи (1, 0, 0, 1);
— line_color: — цвет рамки (0, 0, 1, 1) /
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.15).
Рис. 5.15. Результат выполнения приложения из модуля RectFlatIconButton.py
Если для данной кнопки не задан параметр имя иконки (icon), то по умолчанию будет использоваться иконка «android».
5.5.9. MDFillRoundFlatButton — класс для создания кнопки в виде текста в рамке с округлыми краями и фоном
Класс MDFillRoundFlatButton позволяет создавать кнопку в виде текста в рамке с округлыми краями и фоном. Эта кнопка имеет собственный цвета фона, но при этом можно задавать цвет рамки и цвет текста. В отличие от предыдущей кнопки рядом с текстом можно поставить иконку. Создадим файл FillRoundFlatButton.py и напишем в нем следующий код (листинг 5.14).
Листинг 5.14. Демонстрации работы MDFillRoundFlatButton (модуль FillRoundFlatButton.py)
# модуль FillRoundFlatButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDFillRoundFlatButton:
…… … … text: «КНОПКА»
…… … … #font_size: «25sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: 1, 0, 1, 1
…… … … #md_bg_color: 0, 1, 0, 1
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text: — надпись на кнопке («КНОПКА»);
— #font_size: — размер шрифта надписи («25sp)»;
— #theme_text_color: цветовая тема надписи («Custom»);
— #text_color: — цвет надписи (1, 0, 1, 1);
— #md_bg_color: — цвет фона (0, 1, 0, 1)
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.16).
Рис. 5.16. Результат выполнения приложения из модуля FillRoundFlatButton.py
Как видно из данного рисунка, комбинируя эти параметры и меняя их значения можно получить разные варианты внешнего вида этой кнопки.
5.5.10. MDTextButton — класс для создания текстовых кнопок
Класс MDTextButton позволяет создавать кнопку в виде текста. Эта кнопка не имеет фона, но при этом можно задавать цвет текста. Это аналог кнопки MDFlatButton, но в отличие от нее, в момент нажатия вокруг надписи не появляется цветного фона в виде кнопки, а происходит мигание самой надписи. Создадим файл TextButton.py и напишем в нем следующий код (листинг 5.15).
Листинг 5.15. Демонстрации работы MDTextButton (модуль TextButton.py)
# модуль TextButton.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
…… MDScreen:
…… … … MDTextButton:
…… … … text: «КНОПКА»
…… … … #font_size: «25sp»
…… … … #theme_text_color: «Custom»
…… … … #text_color: 1, 0, 0, 1
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… … … on_press: print («Кнопка нажата»)
…… … … #on_release: print («Кнопка отпущена»)
«'»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— text: — надпись на кнопке («КНОПКА»);
— #font_size: — размер шрифта надписи («25sp)»;
— #theme_text_color: — цветовая тема надписи («Custom»);
— #text_color: — цвет надписи (1, 0, 1, 1);
— pos_hint: — позиция кнопки (в центре окна {«center_x»:.5, «center_y»:.5});
— on_press: — имя функции для обработки события «кнопка нажата» (в данном примере это системная функция print);
— #on_release: — имя функции для обработки события «кнопка отпущена» (в данном примере это системная функция print).
В свойствах, связанных с событиями (on_press, on_release), можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопки. Ниже приведено несколько вариантов внешнего вида этой кнопки при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.17).
Рис. 5.17. Результат выполнения приложения из модуля TextButton.py
5.5.11. MDFloatingActionButtonSpeedDial — класс для создания плавающих кнопок быстрого набора
Класс MDFloatingActionButtonSpeedDial позволяет создать корневую кнопку в виде иконки. После нажатия на корневую кнопку открывается стек (от анг. stack — стопка) или набор новых кнопок. Кнопки этого стека имеют активную иконку с поясняющей надписью. В программе иконки и поясняющие надписи оформляются в виде словаря.
Словарь — это неупорядоченный набор пары элементов «ключ-значение». Это похоже на ассоциативный массив, где каждый ключ хранит определенное значение. Ключ может содержать любой примитивный тип данных, тогда как значение — это произвольный объект Python. Элементы в словаре разделяются запятой»,» и заключаются в фигурные скобки {}. Для стековых кнопок данный словарь будет иметь следующую структуру:
data = {» ключ ': значение», ' ключ ': «значение», «ключ ': значение»}
Здесь ключ — поясняющая надпись, значение — имя иконки.
Нажатие корневой кнопки приводит только к открытию или закрытию набора стековых кнопок. А вот нажатие стековых кнопок может активировать то или иное действие, запрограммированное в приложении.
Создадим файл FABSpeedDial.py и напишем в нем следующий код (листинг 5.16).
Листинг 5.16. Демонстрации работы MDFloatingActionButtonSpeedDial (модуль FABSpeedDial.py)
# модуль FABSpeedDial.py
from kivymd. app import MDApp
from kivy.lang import Builder
KV = «»»
MDScreen:
…… MDFloatingActionButtonSpeedDial:
…… … … # Свойства кнопок
…… … … data: app. data # иконки на кнопках стека
…… … … root_button_anim: True #повернуть корневую кнопку
……… …… …… …… …… …… …… …… …… …… …… при нажатии
…… … … #icon: «language-python» #иконка на корневой кнопке
…… … … #color_icon_root_button: 0,1,0,1 #цвет иконки корневой
…… …… …… …… …… …… …… …… …… …… …… …… …… …… кнопки
…… … … #bg_color_root_button: 1,0,0,1 #цвета фона иконки
……… …… …… …… …… …… …… …… …… …… …… корневой кнопки
…… … … #color_icon_stack_button: 0,1,0,1 #цвет иконок кнопок стека
…… … … #bg_color_stack_button: 1,0,0,1 #цвета фона иконок
…… …… …… …… …… …… …… …… …… …… …… …… кнопок стека
…… … … #label_text_color: 1,0,0,1 #цвета текста кнопок стека
…… … … # вызов функций обработки событий нажатия кнопок
…… … … on_open: app. open () #нажата корневая кнопка
…… … … on_close: app.close () #отжата корневая кнопка
…… … … callback: app.call #нажата стековая кнопка
«»»
class MainApp (MDApp):
…… data = {
…… «Python’: ’language-python’,
…… «PHP»: ’language-php’,
…… «C++': ’language-cpp’}
…… def build (self):
…… … … return Builder. load_string (KV)
…… def open (self):
…… … … print («Корневая кнопка раскрыта»)
…… def close (self):
…… … … print («Корневая кнопка закрыта»)
…… def call (self, button):
…… … … print («Нажата кнопка раскрытого стека»)
…… … … if button. icon == ’language-python’:
…… … … … … print («Кнопка Python’)
…… … … elif button. icon == ’language-php’:
…… … … … … print («Кнопка php’)
…… … … elif button. icon == ’language-cpp’:
…… … … … … print («Кнопка C++»)
MainApp().run ()
Данная кнопка имеет свойства, для которых можно задавать параметры (в вышеприведенном листинге строки с некоторыми свойствами закомментированы):
— data:- словарь с иконками и проясняющими надписями для стековых кнопок (app. data);
— root_button_anim: допускает возможность поворота корневой кнопки при нажатии на 45 град. (True);
— #icon: — задать имя иконки для корневой кнопки («language-python»);
— #color_icon_root_button: — цвет иконки корневой кнопки (0,1,0,1);
— #bg_color_root_button: — цвета фона иконки корневой кнопки (1,0,0,1);
— #color_icon_stack_button: — цвет иконок кнопок стека (0,1,0,1);
— #bg_color_stack_button: — цвета фона иконок кнопок стека (1,0,0,1);
— #label_text_color: — цвета текста кнопок стека (1,0,0,1);
— on_open: — имя функции для обработки события «нажата корневая кнопка», что приводит к открытию списка стековых кнопок (app. open);
— on_close: — имя функции для обработки события «отжата корневая кнопка», что приводит к закрытию списка стековых кнопок app.close ();
— callback: — имя функции для обработки события «нажата стековая кнопка» (app.call)
В базовом классе создан словарь, в который загружены параметры стековых кнопок:
data = {«Python’: ’language-python’, «PHP»: ’language-php’, «C++': ’language-cpp’}
Кроме того, там создана функция build (для загрузки кода из KV) и три функции для обработки следующих событий при нажатии кнопок:
— def open (self) — нажата корневая кнопка;
— def close (self) — отжата корневая кнопка;
— def call (self, button) — нажата стековая кнопка.
Поскольку в стековом наборе три кнопки, то в последней функции реализовано разветвление, позволяющее определить, какая из стековых кнопок была нажата и, в зависимости от этого, запустить тот или иной процесс.
Для ключевой кнопки по умолчанию используется иконка со знаком «+», что символизирует возможность открыть (добавить) панель со стековыми кнопками. Когда стековая панель открыта, то данная иконка поворачивается на 45 град. и превращается в крестик (символ «Х»), что символизирует возможность закрыть (удалить) панель со стековыми кнопками.
Комбинируя свойства и меняя значения их параметров можно получить разные варианты внешнего вида кнопок. Ниже приведено несколько вариантов внешнего вида кнопок при запуске данного приложение с разными комбинациями свойств и значениями их параметров (рис.5.18).
Рис. 5.18. Результат выполнения приложения из модуля FABSpeedDial.py
В терминальном окне PyCharm можно проверить, правильно ли обрабатываются события нажатия кнопок, при нажатии на каждую из кнопок на печать будет выведено соответствующее сообщение (рис.5.19).
Рис. 5.19. Результат обработки событий нажатия кнопок
В свойствах, связанных с событиями нажатия кнопок, можно указать lambda функцию, то есть обработать эти события любой внешней функцией.
5.6. Card — класс для создания панелей (карточек)
Карточки — это часть поверхности экрана, на которой отображается однотипная информация (контент) и элементы для возможного действия с ним. В KivyMD предоставлены два классы карт для использования: MDCard и MDCardSwipe.
5.6.1. MDCard — простая карточка
Выполним ряд последовательных действий, что бы научиться:
— Создавать карты
— Размещать контент на картах
— Размещать элементы интерфейса для воздействий на контент
— Создавать функции, которые активируют действия элементов интерфейса
Создадим файл MDCard_1.py и напишем в нем следующий код (листинг 5.17).
Листинг 5.17. Демонстрации работы MDCard (модуль MDCard_1.py)
# модуль MDCard_1.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDCard:
…… … … size_hint: None, None
…… … … size: «280dp», «180dp»
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Здесь мы создали экран (MDScreen) и поместили на него карточку (MDCard). Для данной карточки задали ограничения:
— Запретили менять размер карточки по ширине и высоте;
— Задали жесткий размер карточки в пикселах (280х180);
— Указали точное место размещения (по центру экрана).
Запустив это простейшее приложение, мы получим следующий результат (рис.5.20).
Рис. 5.20. Результат выполнения приложения из модуля MDCard_1.py
Как видно из данного рисунка, в окне приложения появилась выделенная область, которая, при изменении пропорций экрана, не изменяет размера и положения. Это, по сути, контейнер карточки, который пока не содержит ни одного элемента.
Добавим к карточке несколько элементов. Для этого создадим файл MDCard_2.py и напишем в нем следующий код (листинг 5.17_1).
Листинг 5.17_1. Демонстрации работы MDCard (модуль MDCard_1.py)
# модуль MDCard_2.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDCard:
…… … … orientation: «vertical»
…… … … padding: «8dp»
…… … … size_hint: None, None
…… … … size: «280dp», «180dp»
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 5}
…… MDLabel:
…… … … text: «Заголовок»
…… … … theme_text_color: «Secondary»
…… … … size_hint_y: None
…… … … height: self. texture_size [1]
…… MDSeparator:
…… … … height: «1dp»
…… MDLabel:
…… … … text: «Тело карточки»
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Здесь на карточку добавлены две метки (MDLabel) и линия разделитель (MDSeparator). Запустив приложение в этом варианте, мы получим следующий результат (рис.5.21).
Рис. 5.21. Результат выполнения приложения из модуля MDCard_2.py
Таким образом, на карточку можно помещать различные визуальные компоненты и устанавливать для нах параметры размера, цвета и положения.
5.6.2. MDCardSwipe — карточка со смахиванием
С помощью данного класса можно создать карточку, которую можно развернуть или свернуть с помощью касания со смахиванием.
Чтобы создать карточку с поведением смахивания, необходимо создать новый класс (SwipeToDeleteItem) который наследуется от MDCardSwipe. Это своеобразный контейнер, в котором помещаются все остальные элемента (рис.5.22).
Рис. 5.22. Структура приложения на основе класса MDCardSwipe
В этот контейнер вложен список однострочных элементов (OneLineListItem). Каждый такой элемент имеет два слоя: передний (видимый) слой (MDCardSwipeFrontBox), и задний (скрытый) слой (MDCardSwipeLayerBox). Пользователь приложения с помощью касания со смахиванием имеет возможность сдвинуть передний (видимый) слой. В результате этого откроется задний (скрытый) слой и станут видимыми (и доступными) расположенные на нем элементы интерфейса. Посмотрим, как это работает на простом примере. Создадим файл MDCardSwipe.py и напишем в нем следующий код (листинг 5.18).
Листинг 5.18. Демонстрации работы MDCardSwipe (модуль MDCardSwipe.py)
# модуль MDCardSwipe
from kivymd. app import MDApp
from kivy.lang import Builder
from kivymd.uix.card import MDCardSwipe
from kivy.properties import StringProperty
KV = «»»
<SwipeToDeleteItem>: # контейнер всех элементов
…… size_hint_y: None
…… height: content. height
…… #anchor: «right» # положение скрытого слоя на карточке
…… #type_swipe: «auto» # полное открытие скрытого слоя
…… MDCardSwipeLayerBox: # Контейнер для элементов
…… …… …… …… …… …… …… заднего (скрытого) слоя
…… …… # открываемый элемент заднего (скрытого) слоя
…… …… padding: «8dp» # отступ от края
…… …… MDIconButton: # кнопка с иконкой
…… …… …… icon: «trash-can»
…… …… …… pos_hint: {«center_y»:. 5}
…… …… …… on_press: app.press_button (root) # обработка нажатия кнопки
…… …… MDCardSwipeFrontBox: # Контейнер для элементов
…… …… …… …… …… …… …… …… переднего (видимого) слоя
…… …… … … OneLineListItem: # видимый элемент
…… …… …… …… …… …… …… …… переднего (видимого) слоя
…… …… …… …… id: content
…… …… …… …… text: root. text # список строк из функции on_start
…… …… …… …… …… …… …… …… _no_ripple_effect: True
MDScreen:
…… MDBoxLayout:
…… …… orientation: «vertical»
…… …… spacing: «10dp»
…… …… MDToolbar:
…… …… …… elevation: 10
…… …… …… title: «Класс MDCardSwipe»
…… …… …… ScrollView:
…… …… …… …… scroll_timeout: 100
…… …… …… …… MDList:
…… …… …… …… …… id: md_list
…… …… …… …… …… padding: 0
«»»
class SwipeToDeleteItem (MDCardSwipe): # класс создания
…… …… …… …… …… …… …… …… карточки MDCardSwipe
…… text = StringProperty ()
class MainApp (MDApp): # Базовый класс приложения
…… def __init__ (self, **kwargs):
…… …… super ().__init__ (**kwargs)
…… …… self.screen = Builder. load_string (KV)
…… def build (self):
…… …… return self.screen
…… def on_start (self): # функция создания списка карточек
…… …… for i in range (15):
…… …… …… self.screen.ids.md_list.add_widget (
…… …… …… …… SwipeToDeleteItem
…… …… …… …… (text=f"Однострочный элемент — {i +1}»))
…… def press_button (self, button):
…… …… print («Нажата кнопка на скрытой панели»)
MainApp().run ()
Запустим эту программу и посмотрим на результаты поведения приложения (рис.5.23).
Рис. 5.23. Результат выполнения приложения из модуля MDCardSwipe.py
Как видно из данного рисунка с помощью касаний можно выполнять вертикальный скроллинг списка, открывать и закрывать скрытые слои на любых элементах. Поскольку мы поместили на скрытый слой элемент «кнопка» в виде иконки, то эта кнопка появится при открытии этого слоя. При нажатии на кнопку отработает связанная с ней функция и скрытый слой закроется.
В листинге данного кода есть две строки с закомментированными свойствами:
— #anchor: «right» # положение скрытого слоя на карточке (справа);
— #type_swipe: «auto» # открытие скрытого слоя на всю строку.
Первое свойство позволяет перенести скрытый слой в правую часть строки, а вторая обеспечит развертывание скрытого слоя на всю строку. Если снять комментарии с этих строк, то программа отработает следующим образом (рис.5.24).
Рис. 5.24. Использование свойств класса MDCardSwipe
У класса MDCardSwipe есть еще ряд дополнительных свойств, с которыми можно познакомиться в оригинальной документации на библиотеку KivyMD.
5.7. MDChip — класс для создания компактных элементов интерфейса
Класс MDChip позволяет создать компактные элементы, которые обеспечивают пользователям возможность делать выбор, фильтровать контент или запускать какое либо действие. Чипы имеют форму прямоугольника с округленными углами. Чипы можно объединять в группы и реализовать либо фильтрацию по нескольким признакам, либо выбор только одного элемента из группы. Они могут выполнять и роль мини кнопок, поскольку способны реагировать на события касания.
Создадим файл Chip.py и напишем в нем следующий код (листинг 5.19).
Листинг 5.19. Демонстрации работы MDChip (модуль Chip.py)
# модуль Chip.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDBoxLayout:
…… … … orientation: «vertical»
…… … … MDToolbar:
…… …… … … title: «Примеры Chip»
…… …… … … left_action_items: [[«menu», lambda x: x]]
…… … … ScrollView: # Начало секции скроллинга — — — —
…… …… … … MDGridLayout:
…… … … …… … … padding: dp (10)
…… … … …… … … spacing: dp (10)
……… … …… … … cols: 1
…… … … …… … … adaptive_height: True
…… … … …… … … MDLabel:
…… …… … … …… … … text: «… Варианты…»
…… … … …… … … MDChip:
…… …… … … …… … … text: " Без иконки»
…… …… … … …… … … #color: 1, 0, 0, 1
….. …… … … …… … … text_color: 1, 1, 1, 1
…… …… … … …… … … icon:»»
…… …… … … …… … … on_release: app.press_chip1 (self)
…… … … …… … … MDChip:
…… …… … … …… … … text: " Красный Chip»
…… …… … … …… … … color: 1, 0, 0, 1
…… …… … … …… … … text_color: 1, 1, 1, 1
…… …… … … …… … … icon:»»
…… …… … … …… … … on_release: app.press_chip2 (self)
…… … … …… … … MDChip:
…… …… … … …… … … text: " C иконкой»
…… …… … … …… … … color: 0, 1, 0, 1
…… …… … … …… … … icon: «language-python»
…… …… … … …… … … on_release: app.press_chip2 (self)
…… … … …… … … MDChip:
…… …… … … …… … … text: «С отметкой — v’
…… …… … … …… … … icon: ’city’
…… …… … … …… … … check: True
…… … … …… … … MDSeparator: #####################
…… …… … … …… … … MDLabel:
…… …… … … …… … … text: «Выбор из трех вариантов»
…… …… … … …… … … MDChooseChip:
…… …… …… … … …… … … MDChip:
…… …… …… …… … … …… … … text: «Вариант 1»
…… …… …… …… … … …… … … icon: ’earth’
…… …… …… …… … … …… … … text_color: 1, 1, 1, 1
…… …… …… …… … … …… … … selected_chip_color:.21,.098, 1, 1
…… …… …… … … …… … … MDChip:
…… …… …… …… … … …… … … text: «Вариант 2»
…… …… …… …… … … …… … … icon: ’face’
…… …… …… …… … … …… … … text_color: 1, 1, 1, 1
….. …… …… …… … … …… … … selected_chip_color:.21,.098, 1, 1
…… …… …… … … …… … … MDChip:
…… …… …… …… … … …… … … text: «Вариант 3»
…… …… …… …… … … …… … … icon: ’facebook’
…… …… …… …… … … …… … … text_color: 1, 1, 1, 1
…… …… …… …… … … …… … … selected_chip_color:.21,.098, 1, 1
…… …… … … …… … … MDSeparator: ######################
…… … … # Конец секции скроллинга — — — — — — — — — — — —
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def press_chip1 (self, instance):
…… … … print («Нажат Chip без иконки»)
…… def press_chip2 (self, instance):
…… … … print («Нажат красный Chip’)
MainApp().run ()
В коде данной программы было создано дерево виджетов. Мы создали экран (MDScreen), на который поместили контейнер (MDBoxLayout). В данный контейнер положили заголовок (панель инструментов — MDToolbar), и виджет ScrollView, который еще не использовали в предыдущих примерах. Этот виджет позволяет создать на экране область прокрутки. Все элементы, которые вложены в данный виджет, но не входят в видимую область экрана, могут быть перемещены в видимую область окна путем прокручивания (касания с проскальзыванием). В область прокрутки помещена таблица с одной колонкой, и в каждой строке лежат все нижестоящие элементы. Схематично данное дерево виджетов приведено на рис.5.25.
Рис. 5.25. Дерево виджетов приложения из модуля Chip.py
Более подробно остановимся на структуре дерева виджетов, поскольку все приложения на Kivy строятся на этом принципе. Дерево виджетов — это своеобразный набор контейнеров, вложенных друг в друга. В листинге программ границы между контейнерами задаются отступами от начальной строки программы на языке KV. Текст программы, который начинается с начала строки, определяет внешний контейнер. Если в него нужно вложить другие контейнеры или элементы, то делается отступ в 4 символа и, с пятого символа, начинается следующая строка программного кода. Таким образом, можно вкладывать один контейнер в другой. Внутри каждого контейнера можно разместить либо новый контейнер, либо набор виджетов. Свойства каждого виджета также укладываются в отдельный контейнер с помощью отступов.
В вышеприведенном листинге программы вешний контейнер создается с помощью класса MDScreen. Внутри него сформирован новый контейнер на базе виджета MDBoxLayout. Этот виджет не выполняет никаких действий, он просто указывает на способ расположения элементов. В этом контейнере лежат всего два элемента: видимый виджет MDToolbar с набором свойств (верхняя панель инструментов) и виджет ScrollView. Последний элемент предназначен для выполнения одной важной функции — он создает новый контейнер, содержимое которого будет иметь возможность прокрутки экрана, то есть задает скроллинг. Все визуальные элементы, которые размещены в данном контейнере, но не входят в видимую область экрана, будут иметь возможность «выплывать» в видимую область при прокрутке (касание экрана со смещением).
В прокручиваемой области экрана вложен следующий контейнер — MDGridLayout (таблица из одной колонки). Внутри этого контейнера укладываются виджеты в ячейки таблица (один под другим). В этом контейнере лежат визуальные элементы: метки (MDLabel), чипы (MDChip), разделители (MDSeparator). При этом в одной из ячеек лежит еще один контейнер — MDChooseChip. Внутри него располагается группа чипов (MDChip), функционально связанных между собой. Они служат для реализации выбора пользователем единственного решения из нескольких возможных. Почти каждый визуальный элемент имеет свой вложенный контейнер с набором его свойств.
На первый взгляд дерево виджетов представляет сложный и запутанный инструмент, однако это далеко не так. Разобравшись в его структуре и принципах построения можно убедиться, что это достаточно гибкий и универсальный подход к созданию интерфейса пользователя из набора виджетов.
Если запустить на выполнение приведенный выше программный код, то получим следующий результат (рис.5.26).
Рис. 5.26. Результат выполнения приложения из модуля Chip.py
Как видно из данного рисунка, виджеты Chip имеют разный внешний вид, который задается в таких свойствах, как цвет фона, цвет текста, наличие иконки. При нажатии на первые два виджета (касании) будут отрабатывать функции press_chip1 и press_chip2. Таким образом, виджет Chip может выполнять и роль кнопки, с помощью которой можно в программе запускать те или иные процессы. Полный перечень функций и событий касания виждета Chip приведен в оригинальной документации на Kivy и KivyMD.
5.8. MDDataTables — класс для размещения данных в таблице
MDDataTables это класс, который позволяет организовать отображение информации в виде таблицы, состоящей из строк и столбцов. Таблицы данных могут содержать:
— Интерактивные компоненты (например, кнопки или меню);
— Не интерактивные элементы (например, значки);
— Инструменты для запроса и обработки данных.
MDDataTable позволяет разработчикам сортировать данные по столбцам. Это происходит благодаря использованию внешней функции, которую вы можете привязать при определении столбцов таблицы. Имейте в виду, что функция сортировки должна возвращать список из двух значений в формате — «индекс, данные». Это связано с тем, что список индексов необходим, чтобы позволить MDDataTable отслеживать выбранные строки и, после сортировки данных, обновить их.
Создадим файл DataTable.py и напишем в нем следующий код (листинг 5.20).
Листинг 5.20. Демонстрации работы MDDataTable (модуль DataTable.py)
# модуль DataTable
from kivy.metrics import dp
from kivymd. app import MDApp
from kivymd. uix. datatables import MDDataTable
from kivy.uix.anchorlayout import AnchorLayout
class MainApp (MDApp):
…… def build (self):
…… … … layout = AnchorLayout ()
…… … … self. data_tables = MDDataTable (
…… … … … … size_hint= (0.9, 0.8), use_pagination=True, check=True,
…… … … … … column_data= [(«N», dp (30)),
…… … … … … («Столбец 2», dp (30)),
…… … … … … («Столбец 3», dp (60)),
…… … … … … («Столбец 4», dp (30)),
…… … … … … («Столбец 5», dp (30)),
…… … … … … («Столбец 6», dp (30), lambda *args:
…… … … … … print («Сортировка по столбцу 6»)),
…… … … … … («Столбец 7», dp (30)),],)
…… … … … … layout.add_widget (self. data_tables)
…… … … … … return layout
MainApp().run ()
Это достаточно простой пример, в котором была создана пустая таблица из семи столбцов разной ширины. Для шестого столбца задана функция сортировки данных таблицы по содержанию данного столбца. После запуска данного приложения получим следующий результат (рис.5.27).
Рис. 5.27. Результат выполнения приложения из модуля DataTable.py
Как видно из данного рисунка, в окне приложения поместилось только 4 столбца. Но поскольку данный виджет обеспечивает скроллинг, то можно путем листания «вытащить» на экран любой скрытый столбец или строку. Таблица пустая, поскольку в ней не были загружены данные. Посмотрим, как будет выглядеть таблица, заполненная информацией, и как будут отрабатывать функции сортировки. Для этого создадим файл DataTable2.py и напишем в нем следующий код (листинг 5.21).
Листинг 5.21. Демонстрации работы MDDataTable (модуль DataTable2.py)
# модуль DataTable2
from kivy.metrics import dp
from kivy.uix.anchorlayout import AnchorLayout
from kivymd. app import MDApp
from kivymd. uix. datatables import MDDataTable
class MainApp (MDApp):
…… def build (self):
…… … … layout = AnchorLayout ()
…… … … data_tables = MDDataTable (
…… … … … … … … size_hint= (0.9, 0.6), # положение таблицы
…… … … … … … … # столбцы таблицы (задано 7 столбцов)
…… … … … … … … column_data= [(«N строки», dp (20)),
…… … … … … … … («Столбец 2», dp (30)),
…… … … … … … … («Столбец 3», dp (50), self.sort_on_col_3),
…… … … … … … … («Столбец 4», dp (30)),
…… … … … … … … («Столбец 5», dp (30)),
…… … … … … … … («Столбец 6», dp (30)),
…… … … … … … … («Столбец 7», dp (30), self.sort_on_col_7),],
…… … … … … … … # строки таблицы (задано 5 строк)
…… … … … … … … row_data= [(«1», # столбцы строки 1
…… … … …… … … … … … … («alert», [255/256, 165/256, 0, 1],
……… …… …… …… …… …… «Внимание 1»),
…… … … …… … … … … … … «Текст 13»,
…… … … …… … … … … … … «Текст 14»,
…… … … …… … … … … … … «Текст 15»,
…… … … …… … … … … … … «1 января»,
…… … … …… … … … … … … «1.777», ),
…… … … … … … … («2», # столбцы строки 2
…… … … …… … … … … … … («alert-circle», [1, 0, 0, 1],
……… …… …… …… …… …… «Внимание 2»),
…… … … …… … … … … … … «Текст 23»,
…… … … …… … … … … … … «Текст 24»,
…… … … …… … … … … … … «Текст 25»,
…… … … …… … … … … … … «2 февраля»,
…… … … …… … … … … … … «2.777», ),
…… … … … … … … («3», # столбцы строки 3
…… … … …… … … … … … … («checkbox-marked-circle»,
…… … … …… … … … … … … [39/256, 174/256, 96/256, 1],
……… …… …… …… …… …… «Флажок 3», ),
…… … … …… … … … … … … «Текст 33»,
…… … … …… … … … … … … «Текст 34»,
…… … … …… … … … … … … «Текст 34»,
…… … … …… … … … … … … «3 марта»,
…… … … …… … … … … … … «3.777», ),
…… … … … … … … («4», # столбцы строки 4
……… … …… … … … … … … («checkbox-marked-circle»,
…… … … …… … … … … … … [39/256, 174/256, 96/256, 1],
……… …… …… …… …… …… «Флажок 4», ),
…… … … …… … … … … … … «Текст 43»,
…… … … …… … … … … … … «Текст 44»,
…… … … …… … … … … … … «Текст 45»,
…… … … …… … … … … … … «4 апреля»,
…… … … …… … … … … … … «4.777», ),
…… … … … … … … («5», # столбцы строки 5
…… … … …… … … … … … … («checkbox-marked-circle»,
…… … … …… … … … … … … [39/ 56, 174/256, 96/ 56, 1],
……… …… …… …… …… …… «Флажок 5», ),
…… … … …… … … … … … … «Текст 53»,
…… … … …… … … … … … … «Текст 54»,
…… … … …… … … … … … … «Текст 55»,
…… … … …… … … … … … … «5 марта»,
…… … … …… … … … … … … «5.777», ),],)
…… … … layout.add_widget (data_tables)
…… … … return layout
…… def sort_on_col_3 (self, data):
…… … … return zip (*sorted (enumerate (data), key=lambda l: l [1] [3]))
…… def sort_on_col_7 (self, data):
…… … … return zip (*sorted (enumerate (data), key=lambda l: l [1] [-1]))
MainApp().run ()
В этой программе в базовом классе мы создали контейнер layout на основе класса AnchorLayout (). В этот контейнер поместили таблицу data_tables, которая создана основе класса MDDataTable (). Для этой таблица задали ряд свойств и функций. В частности:
— определили положение таблицы в контейнере (size_hint);
— создали в таблице 7 столбцов (column_data);
— задали имя функции для сортировки по столбцу №3 (self.sort_on_col_3);
— задали имя функции для сортировки по столбцу №7 (self.sort_on_col_7);
— создали в таблице 5 строк (row_data);
— в каждую ячейку таблица занесли тестовые данные (5 строк, 7 столбцов);
— во второй столбец в каждую строку вместе с данными пометили разные иконки и указали их цвет.
В базовом классе создали две функции для сортировки данных столбцов 3 (sort_on_col_3) и 7 (sort_on_col_7).
После запуска данного приложения получим следующий результат (рис.5.28).
Рис. 5.28. Результат выполнения приложения из модуля DataTable2.py
В окне приложения расположена таблица, в верхней и нижней части окна зарезервировано достаточно место для размещения различных элементов управления. Во втором столбце вместе с данными имеется иконка. В окне приложения видно только часть столбцов, однако за счет скроллинга можно вывести на экран скрытые столбцы. Для столбцов 3 и 7 заданы функции сортировки. При активации столбца с сортировкой в заголовке столбца появляется стрелка с указанием направления сортировки (по возрастанию или убыванию). При касании этих стрелок информация во всех строках сортируется по содержимому этого столбца (рис.5.29).
Рис. 5.29. Возможность скроллинга таблицы и сортировки данных при использовании класса DataTable
У класса DataTable есть еще ряд дополнительных свойств:
— разрешить постраничное листание данных (use_pagination);
— отметить строку флажком (check).
Когда таблица содержит большое количество строк, то можно организовать их постраничный вывод (use_pagination). При этом в зону, для которой можно выполнять вертикальный скроллинг, будет выведена только одна страница (по умолчанию она содержит 5 строк). Второе свойство позволяет выделять отдельные строки таблицы. Для демонстрации работы этих свойств создадим файл DataTable3.py и напишем в нем следующий код (листинг 5.21_2).
Листинг 5.21_2. Демонстрации работы MDDataTable (модуль DataTable3.py)
# модуль DataTable3
from kivy.metrics import dp
from kivy.uix.anchorlayout import AnchorLayout
from kivymd. app import MDApp
from kivymd. uix. datatables import MDDataTable
class MainApp (MDApp):
…… def build (self):
…… … … layout = AnchorLayout ()
…… … … data_tables = MDDataTable (
…… …… … … …… … … size_hint= (0.9, 0.8),
…… …… … … …… … … check=«True»,
…… …… … … …… … … use_pagination=True,
…… …… … … …… … … column_data= [
…… … … … … …… …… … … …… … … («No.», dp (30)),
…… … … … … …… …… … … …… … … («Столбец 1», dp (30),),
…… … … … … …… …… … … …… … … («Столбец 2», dp (30)),
…… … … … … …… …… … … …… … … («Столбец 3», dp (30)),
…… … … … … …… …… … … …… … … («Столбец 4», dp (30)),
…… … … … … …… …… … … …… … … («Столбец 5», dp (30)),],
…… …… … … …… … … row_data= [(f» {i +1}», «1», «2», «3», «4», «5»)
…… … … ……… …… … … …… … … for i in range (50)])
…… … … layout.add_widget (data_tables)
…… … … return layout
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.30).
Рис. 5.30. Результат выполнения приложения из модуля DataTable3.py
Как видно из данного рисунка с левой стороны таблицы появилась колонка, в которой можно поставить флажок, а в нижней части таблицы строка, обеспечивающая листание страниц таблицы. По умолчанию на первую страницу выведено всего 5 строк. Этот параметр можно изменить, нажав на кнопку рядом с текстом — Row per page (строка на странице) — рис.5.31.
Рис. 5.31. Меню для выбора количества строк на странице
Поставим флажок в первой колонке заголовка таблицы (выделим все строки), в нижнем меню зададим показ десяти строк на странице, снимем флажок с некоторых строк. Результат представлен на рис. (5.32).
Рис. 5.32. Возможность постраничного листания и выделения части строк в DataTable
Класс DataTable также обеспечивает обработку событий касания строк, изменение цвета текста и фона. Более подробно с этими возможностями DataTable можно познакомиться в оригинальной документации на KivyMD.
5.9. MDDialog — класс для создания окон диалога с пользователями
Диалог — это тип модального окна, которое появляется перед содержимым приложения для предоставления важной информации или запроса решения. Диалоги отключают все функции приложения, когда они появляются, и остаются на экране до тех пор, пока не будут подтверждены, отклонены или выполнены предложенные действие. В KivyMD реализовано несколько типов диалоговых окон:
— диалоговые окна с предупреждениями (вопросами);
— простые диалоговые окна (с информацией);
— диалоговые окна с выбором действия и подтверждением;
— произвольные диалоговые окна.
Диалоги с предупреждениями прерывают действия пользователей с выдачей срочной информацией и предложением выполнить те или иные действия.
В простых диалоговых окнах отображается список элементов, которые демонстрируют результат некоторых выполненных действий, или информируют пользователя о завершении того или иного процесса.
Диалоговые окна подтверждения требуют, чтобы пользователи подтвердили выбор одного или нескольких действий, прежде чем диалоговое окно будет закрыто.
Полноэкранные диалоги заполняют весь экран и содержат действия, требующие выполнения ряда задач.
Для указания типа диалога используются следующие зарезервированные значения свойств: «alert’, «simple’, «confirmation’, «custom’ (по умолчанию — «alert’).
5.9.1. Диалоговое окно с предупреждением
Для реализации данного типа диалогового окна создадим файл Dialog1.py и напишем в нем следующий код (листинг 5.22).
Листинг 5.22. Демонстрации работы класса MDDialog (модуль Dialog1.py)
# модуль Dialog1.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. button import MDFlatButton
from kivymd. uix. dialog import MDDialog
KV = «»»
MDFloatLayout:
…… MDFlatButton:
…… … … text: «Вызов окна диалога»
…… … … pos_hint: {’center_x’:.5, ’center_y’:.5}
…… … … on_release: app.show_alert_dialog ()
«»»
class MainApp (MDApp):
…… dialog = None
…… def build (self):
…… … … return Builder. load_string (KV)
…… def show_alert_dialog (self):
…… … … if not self. dialog:
…… … … … … self. dialog = MDDialog (
…… … … … … … … … … title=«Сбросить настройки?»,
…… … … … … … … … … text=«Это приведет к сбросу настроек по умолчанию»,
…… … … … … … … … … buttons= [MDFlatButton (text=«НЕТ»,
…… … … … … … … … … text_color=self.theme_cls.primary_color,
…… … … … … … … … … on_release=self.closeDialog),
…… … … … … … … … … MDFlatButton (text=«ДА»,
…… … … … … … … … … text_color=self.theme_cls.primary_color,
…… … … … … … … … … on_release=self. ok_Dialog,),],)
…… … … … … self. dialog. open ()
…… def ok_Dialog (self, inst):
…… …… print («Нажата кнопка ДА»)
…… …… self. dialog. dismiss ()
…… def closeDialog (self, inst):
…… …… print («Нажата кнопка НЕТ»)
…… …… self. dialog. dismiss ()
MainApp().run ()
В этой программе в строковой переменной KV была создана кнопка (MDFlatButton), при нажатии на которую в функции show_alert_dialog открывается окно диалога. В этой функции создан объект dialog (диалоговое окно) на основе класса MDDialog, для которого заданы следующие свойства:
— title — заголовок («Сбросить настройки?»);
— text — поясняющий текст («Это приведет к сбросу настроек по умолчанию»);
— buttons — кнопки на основе класса MDFlatButton.
В диалоговом окне dialog на основе класса –MDFlatButton — созданы две кнопки со следующим текстом "НЕТ"и" ДА». При нажатии на первую кнопку будет вызвана функция — closeDialog (закрыть диалог) без выполнения каких либо действий. При нажатии на вторую кнопку будет вызвана функция ok_Dialog (согласиться с предложенными действиями).
Функции closeDialog и ok_Dialog находятся в базовом классе. Первая печатает текст «Нажата кнопка НЕТ» и закрывает окно диалога, вторая в окне терминала печатает текст «Нажата кнопка ДА» и так же закрывает окно диалога. После запуска данного приложения получим следующий результат (рис.5.33).
Рис. 5.33. Результат выполнения приложения из модуля Dialog1.py
5.9.2. Простое диалоговое окно
Для реализации данного типа диалогового окна создадим файл Dialog2.py и напишем в нем следующий код (листинг 5.23).
Листинг 5.23. Демонстрации работы класса MDDialog (модуль Dialog2.py)
# модуль Dialog2.py
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivymd. app import MDApp
from kivymd. uix. dialog import MDDialog
from kivymd.uix.list import OneLineAvatarListItem
KV = «»»
<Item>
…… ImageLeftWidget:
…… … … source: root.source
MDFloatLayout:
…...MDFlatButton:
…… …… text: «Вызов окна диалога»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.5}
…… …… on_release: app.show_simple_dialog ()
«»»
class Item (OneLineAvatarListItem):
…… divider = None
…… source = StringProperty ()
class MainApp (MDApp):
…… dialog = None
…… def build (self):
…… …… return Builder. load_string (KV)
…… def show_simple_dialog (self):
…… …… if not self. dialog:
…… …… …… self. dialog = MDDialog (
…… …… …… title=«Созданы следующие учетные записи»,
…… …… …… type=«simple»,
…… …… …… items= [
…… …… …… Item(text="user01@gmail.com», source="./Images/Alex.jpg»),
…… …… …… Item(text="user02@gmail.com», source="./Images/Anna.jpg»),
…… …… …… Item(text="user02@gmail.com», source="./Images/Anna1.jpg»),],
…… …… ……)
…… …… self. dialog. open ()
MainApp().run ()
В данном приложении был создан дополнительный объект Item на основе класса OneLineAvatarListItem, который позволяет в одной строке совместить изображение и текст. В базовом классе приложения создано диалоговое окно (объект dialog на основе класса MDDialog) и указа тип окна type=«simple» (простое окно). Затем на основе объекта Item сформировано три элемента, для которых указан текст и изображение. После запуска данного приложения получим следующий результат (рис.5.34).
Рис. 5.34. Результат выполнения приложения из модуля Dialog2.py
Как видно из данного рисунка простое диалоговое окно выдает пользователю некую информацию и не имеет никаких элементов управления. Оно закрывается путем касанию любой области экрана за пределами диалогового окна.
5.9.3. Диалоговое окно с выбором действия
Для реализации данного типа диалогового окна создадим файл Dialog3.py и напишем в нем следующий код (листинг 5.24).
Листинг 5.24. Демонстрации работы класса MDDialog (модуль Dialog3.py)
# модуль Dialog3.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. button import MDFlatButton
from kivymd. uix. dialog import MDDialog
from kivymd.uix.list import OneLineAvatarIconListItem
KV = «»»
<ItemConfirm>
…… on_release: root.set_icon (check)
…… CheckboxLeftWidget:
…… … … id: check
…… … … group: «check»
MDFloatLayout:
…… MDFlatButton:
…… … … text: «Вызов окна диалога»
…… … … pos_hint: {’center_x’:.5, ’center_y’:.5}
…… … … on_release: app.show_confirmation_dialog ()
«»»
class ItemConfirm (OneLineAvatarIconListItem):
…… divider = None
…… def set_icon (self, instance_check):
…… … … instance_check.active = True
…… … … check_list = instance_check.get_widgets(instance_check.group)
…… … … for check in check_list:
…… … … … … if check!= instance_check:
…… … … … … … … check.active = False
class MainApp (MDApp):
…… dialog = None
…… def build (self):
…… … … return Builder. load_string (KV)
…… def show_confirmation_dialog (self):
…… … … if not self. dialog:
…… … … … … self. dialog = MDDialog (
…… … … … … … … title=«Мелодия звонка»,
…… … … … … … … type=«confirmation»,
…… … … … … … … size_hint_x=0.8,
…… … … … … … … items= [
…… ….…… … … … … … … ItemConfirm (text=«Callisto»),
…… ….…… … … … … … … ItemConfirm (text=«Luna»),
…… ….…… … … … … … … ItemConfirm (text=«Night»),
…… ….…… … … … … … … ItemConfirm (text=«Solo»),
…… ….…… … … … … … … ItemConfirm (text=«Phobos»),
…… ….…… … … … … … … ItemConfirm (text=«Diamond»),
…… ….…… … … … … … … ItemConfirm (text=«Sirena»),
…… ….…… … … … … … … ItemConfirm (text=«Red music»),
…… ….…… … … … … … … ItemConfirm (text=«Allergio»),
…… ….…… … … … … … … ItemConfirm (text=«Magic»),
…… ….…… … … … … … … ItemConfirm (text=«Tic-tac»),],
……… … … … … … buttons= [
…… ….…… … … … … … … MDFlatButton (
…… ….…… … … … … … … text=«Отменить»,
…… ….…… … … … … … … text_color=self.theme_cls.primary_color,
…… ….…… … … … … … … on_release=self.closeDialog,),
…… ….…… … … … … … … MDFlatButton (
…… …… ….…… … … … … … … text=«Принять»,
…… …… ….…… … … … … … … text_color=self.theme_cls.primary_color,
…… …… ….…… … … … … … … on_release=self. ok_Dialog,),],)
…… …… self. dialog. open ()
…… def ok_Dialog (self, items):
…… …… print («Нажата кнопка Принять»)
…… …… self. dialog. dismiss ()
…… def closeDialog (self, inst):
…… …… print («Нажата кнопка Отменить»)
…… …… self. dialog. dismiss ()
MainApp().run ()
В данной программе создан объект ItemConfirm на основе класса OneLineAvatarIconListItem. В функции def set_icon этого класса всем признакам выбора присвоено значение False (элемент не выбран). Затем в базовом классе приложения в функции def show_confirmation_dialog создан объект self. dialog на основе класса MDDialog. Окну диалога заданы следующие значения свойств:
— title — заголовок диалогового окна («Мелодия звонка»);
— type — тип диалогового окна («confirmation»);
— size_hint_x — отступ границ диалогового окна от границ окна приложения по горизонтали (0.8);
— items […] — элементы диалогового окна в виде массива из одиннадцати элементов.
В базовом классе приложения определены две функции: обработка событий нажатия клавиш «Отменить» и «Принять». После запуска данного приложения получим следующий результат (рис.5.35).
Рис. 5.35. Результат выполнения приложения из модуля Dialog3.py
В окне диалога имеется список элементов, объединенных в группу. Пользователь может выбрать только один элемент из этого списка. Весь список не помещается на экран, но за счет вертикального скроллинга можно вывести на экран любые элементы данного списка.
5.9.4. Произвольное диалоговое окно
Произвольное диалоговое окно может содержать любые визуальные элементы и кнопки. Для реализации данного типа диалогового окна создадим файл Dialog4.py и напишем в нем следующий код (листинг 5.25).
Листинг 5.25. Демонстрации работы класса MDDialog (модуль Dialog4.py)
# модуль Dialog4.py
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd. app import MDApp
from kivymd. uix. button import MDFlatButton
from kivymd. uix. dialog import MDDialog
KV = «»»
<Content>
…… orientation: «vertical»
…… spacing: «12dp»
…… size_hint_y: None
…… height: «230dp»
…… MDTextField:
…… …… hint_text: «Город»
…… MDTextField:
…… …… hint_text: «Улица»
…… MDTextField:
…… …… hint_text: «Дом»
…… MDTextField:
…… …… hint_text: «Квартира»
MDFloatLayout:
…… MDFlatButton:
…… …… text: «Вызов окна диалога»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.5}
…… …… on_release: app.show_confirmation_dialog ()
«»»
class Content (BoxLayout):
…… pass
class MainApp (MDApp):
…… dialog = None
…… def build (self):
…… …… return Builder. load_string (KV)
…… def show_confirmation_dialog (self):
…… …… if not self. dialog:
…… …… …… self. dialog = MDDialog (
…… …… …… …… …… title=«Введите адрес:»,
…… …… …… …… …… type=«custom»,
…… …… …… …… …… size_hint_x=0.8,
…… …… …… …… …… content_cls=Content (),
…… …… …… …… …… buttons= [
………… …… …… …… …… MDFlatButton (text=«Отменить»,
…… … ……… …… …… …… …… text_color=self.theme_cls.primary_color,
…… … ……… …… …… …… …… on_release=self.closeDialog),
………… …… …… …… …… MDFlatButton (text=«Принять»,
…… … ……… …… …… …… …… text_color=self.theme_cls.primary_color,
…… … ……… …… …… …… …… on_release=self. ok_Dialog,),],)
…… … … self. dialog. open ()
…… def ok_Dialog (self, inst):
…… … … print («Нажата кнопка Принять»)
…… … … self. dialog. dismiss ()
…… def closeDialog (self, inst):
…… … … self. dialog. dismiss ()
MainApp().run ()
В данном приложении создан объект Content на основе класса BoxLayout. Это контейнер, в котором описаны параметры диалогового окна и помещена кнопка для его вызова. Сам объект диалоговое окно self. dialog формируется на основе класса MDDialog в функции show_confirmation_dialog. Для диалогового окна заданы следующие свойства:
— title — заголовок («Введите адрес:»);
— type — тип окна («custom»);
— size_hint_x — отступ границ диалогового окна от границ окна приложения по горизонтали (0.8);
— content_cls — элементы окна «Content ()»;
— buttons […] — конопки («Отменить» и «Принять»).
В диалоговом окне dialog на основе класса –MDFlatButton — созданы две кнопки со следующим текстом "Отменить"и" Принять». При нажатии на первую кнопку будет вызвана функция — closeDialog (закрыть диалог). При нажатии на вторую кнопку будет вызвана функция ok_Dialog (согласиться с предложенными действиями).
Функции closeDialog и ok_Dialog находятся в базовом классе. Первая просто закрывает окно диалога, вторая в окне терминала печатает текст «Нажата кнопка ДА» и так же закрывает окно диалога. После запуска данного приложения получим следующий результат (рис.5.36).
Рис. 5.36. Результат выполнения приложения из модуля Dialog4.py
В окне диалога появились поля для ввода текста с подсказками. Пользователь должен заполнить эти поля и либо подтвердить выполненные действия, либо отменить их.
5.10. MDDropdown Item — класс для создания раскрывающегося элемента
Этот класс позволяет вывести на экран элемент с очень коротким содержанием. После касания данного элемента, он раскрывается. Для реализации данного элемента создадим файл DropdownItem.py и напишем в нем следующий код (листинг 5.26).
Листинг 5.26. Демонстрации работы класса MDDropdownItem (модуль DropdownItem.py)
# модуль DropdownItem.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
Screen
…… MDDropDownItem:
…… … … id: drop_item
…… … … pos_hint: {’center_x’:.5, ’center_y’:.5}
…… … … text: «Элемент 1»
…… … … on_release: self.set_item («Элемент 1 после раскрытия»)
…… MDDropDownItem:
…… … … id: drop_item
…… … … pos_hint: {’center_x’:.5, ’center_y’:.4}
…… … … text: «Элемент 2»
…… … … on_release: self.set_item («Элемент 2 после раскрытия»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.37).
Рис. 5.37. Результат выполнения приложения из модуля Dialog4.py
На данном рисунке первый элемент находится в закрытом состоянии, второй раскрытом.
5.11. MDExpansion Panel — класс для создания раскрывающейся панели
Этот класс позволяет вывести на экран панель из двух слоев. На переднем слое панели находится ключевая информация, описывающая содержание скрытой панели. На втором слое панели находится развернутое содержание контента. Прикосновениями к данному виджету можно либо открыть, либо скрыть второй слой панели. Для реализации данного элемента создадим файл ExpansionPanel.py и напишем в нем следующий код (листинг 5.27).
Листинг 5.27. Демонстрации работы класса MDExpansionPanel (модуль ExpansionPanel.py)
# модуль ExpansionPanel.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd. uix. expansionpanel import MDExpansionPanel, MDExpansionPanelThreeLine
KV = «»»
<Content>
…… adaptive_height: True
…… TwoLineIconListItem:
…… …… text: "+7 915-123-45-67»
…… …… secondary_text: «Мобильный тел.»
…… …… IconLeftWidget:
…… …… …… icon: ’phone’
ScrollView:
…… MDGridLayout:
…… …… id: box
…… …… cols: 1
…… …… adaptive_height: True
«»»
class Content (MDBoxLayout):
…… «««# Здесь можно разместить
…… пользовательский контент»»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_start (self):
…… …… for i in range (10):
…… …… …… self.root.ids.box.add_widget (
…… …… …… …… MDExpansionPanel (
…… …… …… …… icon="./Images/icon1.jpg»,
…… …… …… …… content=Content (),
…… …… …… …… panel_cls=MDExpansionPanelThreeLine (
…… …… …… …… …… text=«Заголовок панели»,
…… …… …… …… …… secondary_text=«Вторая строка панели»,
…… …… …… …… …… tertiary_text=«Третья строка панели», )))
MainApp().run ()
В данной программе в функции def on_start базового класса в цикле создано 10 виджетов MDExpansionPanel () со следующими свойствами:
— icon — иконка панели (изображение из файла "./Images/icon1.jpg»);
— content — содержание панели (из класса «Content ()»);
— panel_cls — элементы панели (три строки).
Эти элементы располагаются на переднем слое панели:
— text — заголовок первого слоя панели («Заголовок панели»);
— secondary_text — текст второй строки панели «Вторая строка панели»;
— tertiary_text — текст третьей строки панели («Третья строка панели»).
Содержание второго слоя панели (сам контент) можно описать либо в классе Content (), либо в строке KV (в данном примере этот код находится в строке KV). На этом слое мы расположили двухстрочный виджет TwoLineIconListItem и определили для него следующие свойства:
— text — текст первой строки второго слоя панели (»+7 915-123-45-67»);
— secondary_text — текст второй строки панели («Мобильный тел.»).
Кроме того, на второй слой панели помещен виджет иконка (IconLeftWidget) с изображением телефона (icon: ’phone’). После запуска данного приложения получим следующий результат (рис.5.38).
Рис. 5.38. Результат выполнения приложения из модуля ExpansionPanel.py
В левой части данного рисунка мы видим экран с элементами первого слоя панели, в правой части экран с раскрытым элементом второго слоя. На первом слое видно только 5 элементов первого слоя (остальные не вошли). Поскольку данный класс обеспечивает вертикальный скроллинг экрана, то любой скрытый элемент можно вывести в видимую часть окна путем скроллинга (касанием с проскальзыванием).
5.12. MDFile Manager — класс для работы с файлами
Класс MDFileManager предназначен для поиска и выбора файлов из каталогов устройства. Для реализации данного элемента создадим файл FileManager.py и напишем в нем следующий код (листинг 5.28).
Листинг 5.28. Демонстрации работы класса MDFileManager (модуль FileManager.py)
# модуль FileManager.py
from kivy.core. window import Window
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.filemanager import MDFileManager
from kivymd.toast import toast
KV = «»»
BoxLayout:
…… orientation: ’vertical’
…… MDToolbar:
…… …… title: «Пример MDFileManager»
…… …… left_action_items: [[’menu’, lambda x: None]]
…… …… elevation: 10
…… FloatLayout:
…… …… MDRoundFlatIconButton:
…… …… …… text: «Открыть менеджер»
…… …… …… icon: «folder»
…… …… …… pos_hint: {’center_x’:.5, ’center_y’:.6}
…… …… …… on_release: app.file_manager_open ()
«»»
class MainApp (MDApp):
…… def __init__ (self, **kwargs):
…… … … super ().__init__ (**kwargs)
…… … … Window.bind (on_keyboard=self. events)
…… … … self.manager_open = False
…… … … self.file_manager = MDFileManager (
…… … … … … exit_manager=self. exit_manager,
…… … … … … select_path=self.select_path,
…… … … … … preview=True,)
…… def build (self):
…… …… return Builder. load_string (KV)
…… def file_manager_open (self):
…… …… self.file_manager.show (»/») # вывода менеджера на экран
…… …… self.manager_open = True
…… def select_path (self, path):
…… …… «««Будет вызвана, когда вы нажмете на имя файла
…… …… или кнопка выбора каталога.
…… ……:type path: str;
…… ……:param path: путь к выбранному каталогу или файлу;
…… …… «»»
…… …… print («Выбран файл», path)
…… …… self. exit_manager ()
…… …… toast (path)
…… def exit_manager (self, *args):
…… …… ««» Вызывается, когда пользователь достигает
…… …… корня дерева каталогов.»»»
…… …… self.manager_open = False
…… …… self.file_manager.close ()
…… def events (self, instance, keyboard, keycode, text, modifiers):
…… …… ««» Вызывается при нажатии кнопок на мобильном
…… …… устройстве.»»»
…… …… if keyboard in (1001, 27):
…… …… …… …… if self.manager_open:
…… …… …… …… …… …… self.file_manager.back ()
…… …… return True
MainApp().run ()
В данной программе в функции def __init__ базового класса создается объект file_manager на основе класса MDFileManager (). А в переменной KV создается контейнер BoxLayout, в который вкладываются объекты с их свойствами:
— MDToolbar — верхняя панель;
— FloatLayout — вложенный контейнер;
— MDRoundFlatIconButton — кнопка для открытия окна файл менеджера.
В базовом классе создается ряд функций для обработки событий. После запуска данного приложения получим следующий результат (рис.5.39).
Рис. 5.39. Результат выполнения приложения из модуля FileManager.py
Как видно из данного рисунка, после запуска File Manager в левой части строки ToolBar появляются сведения о корневой папке, а в правой части иконка с крестиком («х») для закрытия окна File Manager. В нижнем правом углу окна находится иконка с изображением флажка («V»). При касании данного флажка окно менеджера закроется и в функцию def select_path будет возвращено имя открытой в менеджере папки. Если коснуться значка с изображением файла, то в функцию def select_path будет возвращено имя выбранного файла. В обоих случаях сразу после выбора окно менеджера файлов закроется, а на экране короткое время будет отображаться имя выбранного файла или папки.
5.13. FitImage — класс для размещения изображений
Класс FitImag представляет собой контейнер, в котором можно поместить изображение и определить параметры его размера. Можно задать изображению фиксированный размер, и он будут постоянными вне зависимости от размеров экрана. Можно адаптировать изображение под размер экрана. Можно также задавать форму рамки, в которой находится изображение.
Для демонстрации использования этого класса, создадим файл FitImage11.py и напишем в нем следующий код (листинг 5.29).
Листинг 5.29. Демонстрации работы класса FitImage (модуль FitImage11.py)
# модуль FitImage11.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…...padding: 15
…… FitImage:
…… …… source: "./Images/forest.jpg»
…… …… size_hint_x: 1
…… …… size_hint_y: 1
…… …… radius: [20, 30, 0, 0,]
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
Здесь мы создали корневой виджет на базе класса MDBoxLayout, в него поместили контейнер FitImage, и уже в данный контейнер положили изображение. У рамки изображения скруглили два верхних угла. После запуска данного приложения получим следующий результат (рис.5.40).
Рис. 5.40. Результат выполнения приложения из модуля FitImage11.py
Как видно из данного рисунка, после изменения размера и формы экрана изображение адаптировалось под его размеры.
Теперь создадим файл FitImage12.py и напишем в нем следующий код (листинг 5.30).
Листинг 5.30. Демонстрации работы класса FitImage (модуль FitImage12.py)
# модуль FitImage12.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… padding: 15
…… FitImage:
…… …… source: "./Images/forest.jpg»
…… …… size_hint_x: None
…… …… size_hint_y: None
…… …… height: «540dp’
…… …… width: «250dp’
…… …… radius: [20, 30, 0, 0,]
«»»
class MainApp (MDApp):
…...def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В этом программном модуле мы жестко зафиксировали размеры изображения (540х250 пикселей). После запуска данного приложения получим следующий результат (рис.5.41).
Рис. 5.41. Результат выполнения приложения из модуля FitImage12.py
Как видно из данного рисунка, после изменения размера и формы экрана размеры самого изображения не изменились.
5.14. Image — класс для загрузки изображений
Класс Imag обеспечивает загрузку изображения в родительский контейнер. Изображение занимает все пространство родительского контейнера, и его размеры масштабируются, подстраиваясь под размер родительского контейнера.
Для демонстрации использования этого класса, создадим файл Image.py и напишем в нем следующий код (листинг 5.31).
Листинг 5.31. Демонстрации работы класса Image (модуль Image.py)
# модуль Image.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… padding: 15
…… Image:
…… …… source: "./Images/forest.jpg»
…… …… size: self. texture_size
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
Здесь мы создали корневой виджет на базе класса MDBoxLayout и в него положили изображение. В качестве размера изображения в свойстве size указали использовать оригинальные размеры и текстуру изображения. После запуска данного приложения получим следующий результат (рис.5.42).
Рис. 5.42. Результат выполнения приложения из модуля Image.py
В этом примере изображение было загружено из папки Images того устройства, на котором запущен программный модуль. В Kivy имеется возможность загрузки изображения из сети интернет с использованием класса AsyncImage. Для демонстрации такой возможности, создадим файл Image_Async.py и напишем в нем следующий код (листинг 5.32).
Листинг 5.32. Демонстрации работы класса AsyncImage (модуль Image_Async.py)
# модуль Image_Async.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… padding: 15
…… AsyncImage:
…… …… source: 'https://kivy.org/logos/kivy-logo-black-64.png'
…… …… size: self. texture_size
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В данной программе реализована загрузка изображения из сети интернет, в частности указана ссылка на логотип фреймворка Kivy. После запуска данного приложения получим следующий результат (рис.5.43).
Рис. 5.43. Результат выполнения приложения из модуля Image_Async.py
5.15. Image List — класс формирования контейнера для размещения изображений
Класс Image List (список изображений) позволяет отобразить коллекцию изображений в организованной таблице. В KivyMD есть два подкласса, которые организуют вывод коллекции изображений:
— SmartTileWithStar — с Tile (плиткой, панелью) в виде звезд;
— SmartTileWithLabel — с Tile (плиткой, панелью) в виде метки.
5.15.1. Подкласс SmartTileWithStar
Данный подкласс обеспечивает вывод изображений с полупрозрачной панелью, на которой можно поместить от 1 до 5 звезд. Для реализации вывода списка изображений на основе SmartTileWithStar создадим файл ImageList1.py и напишем в нем следующий код (листинг 5.33).
Листинг 5.33. Демонстрации работы подкласса SmartTileWithStar (модуль ImageList1.py)
# модуль ImageList1
from kivymd. app import MDApp
from kivy.lang import Builder
KV = «»»
<MyTile@SmartTileWithStar>
…… size_hint_y: None
…… size_hint_x: None
…… height: «340dp»
…… width: «240dp»
ScrollView:
…… MDGridLayout:
…… …… cols: 3
…… …… adaptive_height: True
…… …… adaptive_width: True
…… …… padding: dp (5), dp (5)
…… …… spacing: dp (5)
…… …… MyTile:
…… …… …… stars: 2
…… …… …… source: "./Images/Ballon.jpg»
…… …… MyTile:
stars: 3
source: "./Images/Elena.jpg»
…… …… MyTile:
…… …… …… stars: 4
…… …… …… source: "./Images/Flora.jpg»
…… …… MyTile:
…… …… …… stars: 5
…… …… …… source: "./Images/Fortuna.jpg»
…… …… MyTile:
…… …… …… stars: 5
…… …… …… source: "./Images/Ganna.jpg»
…… …… MyTile:
…… …… …… stars: 3
…… …… …… source: "./Images/Gorox.jpg»
«»»
class MyApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MyApp().run ()
В данной программе в строковой переменной KV создали объект MyTile на основе класса SmartTileWithStar (MyTile@SmartTileWithStar) и задали размеры ячейки этого объекта (height: «340dp», width: «240dp»). Затем в контейнер, который обеспечивает скроллинг (ScrollView), поместили другой контейнер — таблицу (MDGridLayout). Эта таблица состоит из 3-х колонок (cols: 3), имеет возможность адаптироваться по ширине и высоте, для нее заданы расстояния отступов от верхнего угла экрана и между ячейками. В ячейки таблицы положили шесть панелей (MyTile), для каждой указали количество отображаемых звезд и имя файла с изображением. После запуска данного приложения получим следующий результат (рис.5.44).
Рис. 5.44. Результат выполнения приложения из модуля ImageList1.py
На данном рисунке окно приложения растянуто так, чтобы в него вошли все 6 изображений. Это сделано для того, чтобы показать, что программный модуль действительно выдал таблицу со всеми изображениями. Однако смартфон имеет совершенно другие размеры и пропорции экрана. Изменим размер окна приложения и посмотрим, как этот элемент будет выглядеть на мобильном устройстве (рис.5.45).
Рис. 5.45. Возможность скроллинга изображений в модуле ImageList1.py
Если сравнить два последних рисунка, то видно, что за счет вертикального и горизонтального скроллинга в видимую часть окна приложения можно переместить любое изображение.
5.15.2. Подкласс SmartTileWithLabel
Данный подкласс обеспечивает вывод изображений с полупрозрачной панелью, на которой можно вывести текст разного размера и цвета. Для реализации вывода списка изображений на основе SmartTileWithLabel создадим файл ImageList2.py и напишем в нем следующий код (листинг 5.34).
Листинг 5.34. Демонстрации работы подкласса SmartTileWithLabel (модуль ImageList2.py)
# модуль ImageList2.py
from kivymd. app import MDApp
from kivy.lang import Builder
KV = «»»
<MyTile@SmartTileWithLabel>
…… size_hint_y: None
…… size_hint_x: None
…… height: «340dp»
…… width: «240dp»
ScrollView:
…… MDGridLayout:
…… …… cols: 3
…… …… adaptive_height: True
…… …… adaptive_width: True
…… …… padding: dp (5), dp (5)
…… …… spacing: dp (5)
…… …… MyTile:
…… …… …… source: "./Images/Ballon.jpg»
…… …… …… text:» [size=26] Платье — «Баллон» [/size]
…… …… …… … … …… …… [size=14]Ballon.jpg [/size]»
…… …… MyTile:
…… …… …… source: "./Images/Elena.jpg»
…… …… …… text:» [size=26] Платье — «Елена» [/size]
…… …… …… … … …… …… [size=14]Elena.jpg [/size]»
…… …… …… tile_text_color: app.theme_cls.accent_color
…… …… MyTile:
…… …… …… source: "./Images/Flora.jpg»
…… …… …… text:» [size=26] Платье — «Флора» [/size]
…… …… …… … … …… …… [size=14]Flora.jpg [/size]»
…… …… MyTile:
…… …… …… source: "./Images/Fortuna.jpg»
…… …… …… text:» [size=26] Платье — «Фортуна» [/size]
.… … …… …….. … …… …… [size=14]Fortuna.jpg [/size]»
…… …… MyTile:
…… …… …… source: "./Images/Ganna.jpg»
…… …… …… text:» [size=26] Платье — «Жанна» [/size]
…… …… …… … … …… …… [size=14]Ganna.jpg [/size]»
…… …… MyTile:
…… …… …… source: "./Images/Gorox.jpg»
…… …… …… text:» [size=26] Платье — «Горох» [/size]
…… …… …… … … …… …… [size=14]Gorox.jpg [/size]»
«»»
class MyApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MyApp().run ()
Текст этого программного кода аналогичен тексту, предыдущего листинга. Однако здесь для MyTile задано свойство text. Для всех элементов указан только размер текста в формате:
text:»[size=26] Платье — «Флора»[/size] [size=14]Flora.jpg [/size]»
Для одного элемента задан еще и цвет текста в формате:
tile_text_color: app.theme_cls.accent_color
После запуска данного приложения получим следующий результат (рис.5.46).
Рис. 5.46. Результат выполнения приложения из модуля ImageList2.py
5.16. MDLabel — класс для вывода текста
Класс MDLabel (метка, этикетка) предназначен для отображения в окне приложения текста различных размеров и цветов, а также иконок (подкласс MDIcon). Для реализации вывода текста на основе MDLabel создадим файл Label.py и напишем в нем следующий код (листинг 5.35).
Листинг 5.35. Демонстрации работы класса MDLabel (модуль Label.py)
# модуль Label
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
Screen:
…… BoxLayout:
…… …… orientation: «vertical»
…… …… MDToolbar:
…… …… …… title: «Класс MDLabel»
…… …… MDLabel:
…… …… …… text: «Текст 1»
…… …… MDLabel:
…… …… …… text: «Текст 2»
…… …… …… theme_text_color: «Custom»
…… …… …… text_color: 1, 0, 0, 1
…… …… MDLabel:
…… …… …… text: «Текст 3»
…… …… …… font_size: dp (35)
…… …… …… halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В данной программе в окно приложения выведено 3 метки:
— text: «Текст 1» — с параметрами по умолчанию;
— text: «Текст 2» — с параметрами указания цвета (theme_text_color: «Custom», text_color: 1, 0, 0, 1);
— text: «Текст 3» — с параметрами указания размера и места положения (font_size: dp (35), halign: «center»).
После запуска данного приложения получим следующий результат (рис.5.47).
Рис. 5.47. Результат выполнения приложения из модуля Label.py
Для реализации вывода иконок на основе MDIcon а создадим файл Icon.py и напишем в нем следующий код (листинг 5.36).
Листинг 5.36. Демонстрации работы класса MDIcon (модуль Icon.py)
# модуль Icon
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
Screen:
…… BoxLayout:
…… … … orientation: «vertical»
…… … … MDToolbar:
…… …… … … title: «Класс MDIcon»
…… … … MDIcon:
…… …… … … #halign: «center»
…… …… … … icon: «language-python»
…… … … MDIcon:
…… …… … … icon: «language-python»
…… …… … … theme_text_color: «Custom»
…… …… … … text_color: 1, 0, 0, 1
…… … … MDIcon:
…… …… … … icon: «language-python»
…… …… … … halign: «center»
…… …… … … font_size: dp (45)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В данной программе в окно приложения выведено 3 иконки «language-python» с различными параметрами:
— с параметрами по умолчанию;
— с параметрами указания цвета (theme_text_color: «Custom», text_color: 1, 0, 0, 1);
— с параметрами указания размера и места положения (font_size: dp (35), halign: «center»).
После запуска данного приложения получим следующий результат (рис.5.48).
Рис. 5.48.
Результат выполнения приложения из модуля Icon.py
5.17. List — класс для создания списка элементов
Списки представляют собой непрерывную группу текста или изображений. Они состоят из элементов с основным содержанием и дополнительными действиями, которые представлены значками и текстом. Список состоит из одного непрерывного столбца, разбитого на строки. В каждой строке можно совместить иконку или изображение с несколькими строчками текста. Нажатие на элемент списка расширяет его на весь экран, отображая другой контейнер с набором своих элементов.
В KivyMD представлены следующие классы элементов списка для использования:
— ListItems — контейнер со строками текста:
— ListItems — контейнер со строками виджетов.
5.17.1. MDList — класс для создания списка со строками текста
Каждый из этих классов имеет множество свойств и настроек, позволяющих создать достаточно гибкий интерфейс пользователя. В частности контейнер, содержащий только текст, имеет три подкласса:
— OneLineListItem — однострочный текст;
— TwoLineListItem — двухстрочный текст;
— ThreeLineListItem — трехстрочный текст.
Для реализации списка с однострочным текстом создадим файл ListText1.py и напишем в нем следующий код (листинг 5.37).
Листинг 5.37. Демонстрации работы класса MDList (модуль ListText1.py)
# модуль ListText1.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.list import OneLineListItem
KV = «»»
ScrollView:
…… MDList:
…… … … id: container
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def on_start (self):
…… … … for i in range (20):
…… … … … … self.root.ids.container.add_widget (
…… … … … … … … OneLineListItem (text=f"Однострочный элемент {i}»))
MainApp().run ()
В данной программе создан контейнер для скроллинга элементов (ScrollView), положили в него объект MDList и дали ему идентификатор — container. В головном модуле положили в этот контейнер 20 элементов — OneLineListItem с тестом «Однострочный элемент» и номером данного элемента. После запуска данного приложения получим следующий результат (рис.5.49).
Рис. 5.49. Результат выполнения приложения из модуля ListText1.py
Список в окне приложения можно листать вниз и вверх (скроллинг), при касании элемента списка возникает соответствующее событие, которое можно перехватить и обработать.
Для реализации списка с различным количеством строк текста в одном элементе (одна, две, три) и обработкой события касания элемента создадим файл ListText2.py и напишем в нем следующий код (листинг 5.38).
Листинг 5.38. Демонстрации работы класса MDList (модуль ListText2.py)
# модуль ListText2.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
ScrollView:
…… MDList:
…… … … OneLineListItem:
…… …… … … text: «Однострочный элемент»
…… …… … … on_release: print («Нажата строка 1»)
…… … … TwoLineListItem:
…… …… … … text: «Двухстрочный элемент»
…… …… … … secondary_text: «Это вторая строк»
…… …… … … on_release: print («Нажата строка 2»)
…… … … ThreeLineListItem:
…… …… … … text: «Трехстрочный элемент»
…… …… … … secondary_text: «Это вторая строк»
…… …… … … tertiary_text: «Это третья строк»
…… …… … … on_release: print («Нажата строка 3»)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Здесь в списке (MDList) создан однострочный элемент (OneLineListItem), двухстрочный элемент (TwoLineListItem), трехстрочный элемент (ThreeLineListItem). К каждому элементу назначена функция обработки события касания (on_release). После запуска данного приложения получим следующий результат (рис.5.50).
Рис. 5.50. Результат выполнения приложения из модуля ListText2.py
5.17.2. MDList — класс для создания списка с виджетами
KivyMD предоставляет такие базовые классы — контейнеры списков для виджетов:
— ImageLeftWidget — рисунок слева,
— ImageRightWidget –рисунок справа,
— IconRightWidget –иконка слева,
— IconLeftWidget — иконка справа.
Позволяет использовать элементы с настраиваемыми виджетами слева:
— OneLineAvatarListItem — однострочный список с аватаром;
— TwoLineAvatarListItem — двухстрочный список с аватаром;
— ThreeLineAvatarListItem — трехстрочный список с аватаром;
— OneLineIconListItem — однострочный список с иконкой;
— TwoLineIconListItem — двухстрочный список с иконкой;
— ThreeLineIconListItem — трехстрочный список с иконкой.
Так же позволяет использовать элементы с настраиваемыми виджетами слева и справа:
— OneLineAvatarIconListItem — однострочный список с аватаром или иконкой;
— TwoLineAvatarIconListItem — двухстрочный список с аватаром или иконкой;
— ThreeLineAvatarIconListItem — трехстрочный список с аватаром или иконкой.
Для реализации списка с виджетами создадим файл ListText3.py и напишем в нем следующий код (листинг 5.39).
Листинг 5.39. Демонстрации работы класса MDList (модуль ListText3.py)
# модуль ListText3.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. dialog import MDDialog
KV = «»»
ScrollView:
…… MDList:
.… ….. … OneLineAvatarListItem:
……… ….. … text: «Однострочный + аватар»
……… ….. … on_release: app. dialog1 ()
……… ….. … ImageLeftWidget:
…… … …… ….. … source: "./Images/Alex.jpg»
.… ….. … TwoLineAvatarListItem:
……… ….. … text: «Двухстрочный + аватар»
……… ….. … secondary_text: «Вторая строка»
……… ….. … on_release: app. dialog2 ()
……… ….. … ImageLeftWidget:
…… … …… ….. … source: "./Images/Anna.jpg»
.… ….. … ThreeLineAvatarListItem:
……… ….. … text: «Двухстрочный + аватар»
……… ….. … secondary_text: «Вторая строка»
……… ….. … tertiary_text: «Третья строка»
……… ….. … ImageLeftWidget:
…… … …… ….. … source: "./Images/Anna1.jpg»
.… ….. … OneLineIconListItem:
……… ….. … text: «Однострочный + иконка»
……… ….. … on_release: app. dialog3 ()
……… ….. … IconLeftWidget:
…………… ….. … icon: «language-python»
.… ….. … TwoLineIconListItem:
……… ….. … text: «Двухстрочный + иконка»
……… ….. … secondary_text: «Вторая строка»
……… ….. … IconLeftWidget:
…… … …… ….. … icon: «language-php»
.… ….. … ThreeLineIconListItem:
……… ….. … text: «Трехстрочный + иконка»
……… ….. … secondary_text: «Вторая строка»
……… ….. … tertiary_text: «Третья строка»
……… ….. … IconLeftWidget:
…… … …… ….. … icon: «language-csharp»
.… ….. … OneLineAvatarIconListItem:
……… ….. … text: «1 строка +2 иконки»
……… ….. … on_release: app. dialog4 ()
……… ….. … IconLeftWidget:
…… … …… ….. … icon: «plus»
…… … …… ….. … on_release: app. dialog5 ()
……… ….. … IconRightWidget:
…… … …… ….. … icon: «minus»
…… … …… ….. … on_release: app. dialog6 ()
.… ….. … TwoLineAvatarIconListItem:
……… ….. … text: «2 строки +2 иконки»
……… ….. … secondary_text: «Вторая строка»
……… ….. … IconLeftWidget:
…… … …… ….. … icon: «language-csharp»
……… ….. … IconRightWidget:
…… … …… ….. … icon: «language-cpp»
.… ….. … ThreeLineAvatarIconListItem:
……… ….. … text: «3 строки +2 иконки»
……… ….. … secondary_text: «Вторая строка»
……… ….. … tertiary_text: «Третья строка»
……… ….. … IconLeftWidget:
…… … …… ….. … icon: «library»
……… ….. … IconRightWidget:
…… … …… ….. … icon: «license»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def dialog1 (self):
…… …… dialog = MDDialog (text=«Однострочный + аватар»)
…… …… dialog. open ()
…… def dialog2 (self):
…… …… dialog = MDDialog (text=«Двухстрочный + аватар»)
…… …… dialog. open ()
…… def dialog3 (self):
…… …… dialog = MDDialog (text=«Однострочный + иконка»)
…… …… dialog. open ()
…… def dialog4 (self):
…… …… dialog = MDDialog (text=«Однострочный +2 иконки»)
…… …… dialog. open ()
…… def dialog5 (self):
…… …… dialog = MDDialog (text=«Нажата левая иконка»)
…… …… dialog. open ()
…… def dialog6 (self):
…… …… dialog = MDDialog (text=«Нажата правая иконка»)
…… …… dialog. open ()
MainApp().run ()
В данной программе показано несколько возможных вариантов строк списка с виджетами (однострочные, двухстрочные, трехстрочные, с аватаром на основе изображений, с иконками слева от текста и с двух сторон). Кроме того, для некоторых строк созданы функции обработки событий: касание строки, касания левой иконки, касание правой иконки. Поскольку все строки списка не помещаются в окно приложения, то реализован вертикальный скроллинг. После запуска данного приложения получим следующий результат (рис.5.51).
Рис. 5.51.
Результат выполнения приложения из модуля ListText3.py
Здесь в левой части рисунка показан экран до скроллинга, в правой части рисунка — после вертикального скроллинга. Возможности обработки событий при касании строки списка, правой и левой иконок приведены на рис.5.52.
Рис. 5.52. Результат обработки событий в приложении из модуля ListText2.py
Здесь в левой части рисунка показан экран при касании строки с двумя иконками, в средней части рисунка — после касания левой иконки, в правой части — после касания правой иконки. То есть на касание разных частей строки списка можно запрограммировать обработку трех разных событий.
5.18. MDSwiper — класс для создания слайдера
Класс MDSwiper позволяет создать слайдер для прокрутки изображений. Для реализации слайдера создадим файл MDSwiper.py и напишем в нем следующий код (листинг 5.40).
Листинг 5.40. Демонстрации работы класса MDSwiper (модуль MDSwiper.py)
# модуль MDSwiper.py
from kivymd. app import MDApp
from kivy.lang. builder import Builder
kv = «»»
MDScreen:
…… MDToolbar:
…… …… id: toolbar
…… …… title: «Пример MDSwiper»
…… …… elevation: 10
…… …… pos_hint: {«top»: 1}
…… MDSwiper:
…… …… size_hint_y: None
…… …… height: root. height — toolbar. height — dp (20)
…… …… y: root. height — self. height — toolbar. height — dp (10)
…… MDSwiperItem:
…… …… FitImage:
…… …… …… source: "./Images/Ballon.jpg»
…… …… …… radius: [10,]
…… MDSwiperItem:
…… …… FitImage:
…… …… …… source: "./Images/Elena.jpg»
…… …… …… radius: [10,]
…… MDSwiperItem:
…… …… FitImage:
…… …… …… source: "./Images/Flora.jpg»
…… …… …… radius: [10,]
…… MDSwiperItem:
…… …… FitImage:
…… …… …… source: "./Images/Fortuna.jpg»
…… …… …… radius: [10,]
…… MDSwiperItem:
…… …… FitImage:
…… …… …… source: "./Images/Gorox.jpg»
…… …… …… radius: [10,]
«»»
class Main (MDApp):
…… def build (self):
…… … … return Builder. load_string (kv)
Main().run ()
В данной программе в строковой переменной KV был создан контейнер MDScreen и в него поместили верхнюю панель инструментов (MDToolbar) и слайдер (MDSwiper). В контейнер MDSwiper создали 5 элементов, или слайдов (MDSwiperItem). В каждом слайде создали контейнер (FitImage — вместить изображение). Для каждого изображения, размещенного в этом контейнере, задали свойства:
— source: — имя файла с изображением (например,"./Images/Gorox.jpg»);
— radius: — радиус округления углов рамки слайда ([10,]).
После запуска данного приложения получим следующий результат (рис.5.53).
Рис. 5.53. Результат выполнения приложения из модуля MDSwiper.py
Слайды можно перелистывать, поскольку в данном объекте зашита возможность скроллинга. В результате перелистывания на экране будет находиться изображение одного слайда, причем его размер будет несколько больше, чем размеры соседних сладов.
На базе MDSwiper можно реализовать слайды, совмещенные с тестом и иконками, причем можно обработать событие нажатия иконки. Для реализации такого варианта слайдера создадим файл MDSwiper1.py и напишем в нем следующий код (листинг 5.41).
Листинг 5.41. Демонстрации работы класса MDSwiper (модуль MDSwiper1.py)
# модуль MDSwiper1.py
from kivymd. app import MDApp
from kivy.lang. builder import Builder
kv = «»»
<MagicButton@MagicBehavior+MDIconButton>
MDScreen:
…… MDToolbar:
…… … … id: toolbar
…… … … title: «Пример MDSwiper»
…… … … elevation: 10
…… … … pos_hint: {«top»: 1}
…… … … MDSwiper:
…… …… … … size_hint_y: None
…… …… … … height: root. height — toolbar. height — dp (20)
…… …… … … y: root. height — self. height — toolbar. height — dp (10)
…… …… … … MDSwiperItem:
………… …… … … RelativeLayout:
…… ………… …… … … FitImage:
…… …… ………… …… … … source: "./Images/Elena.jpg»
………… ………… …… … … radius: [10,]
…… ………… …… … … MDBoxLayout:
…… …… ………… …… … … adaptive_height: True
…… …… ………… …… … … spacing: «12dp»
…… …… ………… …… … … MagicButton:
…… …… …… ………… …… … … id: icon
…… …… …… ………… …… … … icon: «weather-sunny»
…… …… …… ………… …… … … user_font_size: «56sp»
…… …… …… ………… …… … … on_press: print («Нажата кнопка
……… …… …… …… …… …… …… …… …… …… …… …… …… Елена»)
…… …… ………… …… … … MDLabel:
…… …… …… ………… …… … … text: «Платье Елена»
…… …… …… ………… …… … … font_style: «H5»
…… …… …… ………… …… … … size_hint_y: None
…… …… …… ………… …… … … height: self. texture_size [1]
…… …… …… ………… …… … … pos_hint: {«center_y»:. 5}
…… …… … … MDSwiperItem:
………… …… … … RelativeLayout:
…… ………… …… … … FitImage:
…… …… ………… …… … … source: "./Images/Fortuna.jpg»
…… …… ………… …… … … radius: [10,]
………… …… … … MDBoxLayout:
…… …… ………… …… … … adaptive_height: True
…… …… ………… …… … … spacing: «12dp»
…… …… ………… …… … … MagicButton:
…… …… …… ………… …… … … id: icon
…… …… …… ………… …… … … icon: «weather-sunny»
…… …… …… ………… …… … … user_font_size: «56sp»
…… …… …… ………… …… … … on_press: print («Нажата кнопка
…… …… …… …… …… …… …… …… …… …… …… …… Фортуна»)
…… …… ………… …… … … MDLabel:
…… …… …… ………… …… … … text: «Платье Фортуна»
…… …… …… ………… …… … … font_style: «H5»
…… …… …… ………… …… … … size_hint_y: None
…… …… …… ………… …… … … height: self. texture_size [1]
…… …… …… ………… …… … … pos_hint: {«center_y»:. 5}
…… …… … … MDSwiperItem:
………… …… … … RelativeLayout:
…… ………… …… … … FitImage:
…… …… ………… …… … … source: "./Images/Gorox.jpg»
…… …… ………… …… … … radius: [10,]
…… ………… …… … … MDBoxLayout:
…… …… ………… …… … … adaptive_height: True
…… …… ………… …… … … spacing: «12dp»
…… …… ………… …… … … MagicButton:
…… …… …… ………… …… … … id: icon
…… …… …… ………… …… … … icon: «weather-sunny»
…… …… …… ………… …… … … user_font_size: «56sp»
…… …… …… ………… …… … … on_press: print («Нажата кнопка
…… …… …… …… …… …… …… …… …… …… …… …… Горох»)
…… …… ………… …… … … MDLabel:
…… …… …… ………… …… … … text: «Платье Горох»
…… …… …… ………… …… … … font_style: «H5»
…… …… …… ………… …… … … size_hint_y: None
…… …… …… ………… …… … … height: self. texture_size [1]
…… …… …… ………… …… … … pos_hint: {«center_y»:. 5}
«»»
class Main (MDApp):
…… def build (self):
…… … … return Builder. load_string (kv)
Main().run ()
В данной программе в строковой переменной KV был создан пользовательский класс MagicButton (на основе базовых классов MagicBehavior+MDIconButton) и контейнер MDScreen, в который поместили верхнюю панель инструментов (MDToolbar) и слайдер (MDSwiper). В контейнер MDSwiper создали 3 элемента, или слайда (MDSwiperItem). В каждом слайде создали контейнер RelativeLayout, в него вложили два элемета: контейнер (FitImage — вместить изображение) и MDBoxLayout. Для каждого изображения, размещенного в контейнере FitImage, задали свойства:
— source: — имя файла с изображением (например, "./Images/Gorox.jpg»);
— radius: — радиус округления углов рамки слайда ([10,]).
А в контейнер MDBoxLayout положили два элемента: иконку (MagicButton), и метку (MDLabel). Для каждого из этих элементов задали свой набор свойств. После запуска данного приложения получим следующий результат (рис.5.54).
Рис. 5.54. Результат выполнения приложения из модуля MDSwiper1.py
Как видно из данного рисунка, поверх изображения появились полупрозрачная иконка и текст. Событие касания иконки обрабатывается связанной с ней функцией. Это позволяет запрограммировать выполнение различных действий с текущим слайдом.
5.19. Menu — класс для создания меню
Класс Menu служит для отображения списка вариантов действий пользователя на временной поверхности. Этот список появляются тогда, когда пользователь взаимодействует с кнопкой или другим элементом управления, а также после выполнения некоторых действий. Меню позволяет пользователю сделать выбор действия из нескольких возможных вариантов. Меню может быть открытым или раскрывающимся. Поскольку экраны мобильных устройств имеют ограниченные размеры, то преимущественно используются раскрывающиеся меню. Если меню имеет небольшое количество опция, то оно может быть и открытым. Каждая опция меню может состоять из иконок, из текста, из комбинации текста и иконок.
Каждый пункт меню должен быть связан с функцией, выполняющей запрограммированные действия. В KivyMD имеется несколько вариантов создания меню, рассмотрим каждый из этих вариантов.
5.19.1. MDDropdownMenu — класс для создания выпадающих строковых меню
В этом случае на экране располагается элемент (кнопка, надпись), который занимает на экране мало места, но при взаимодействии с этим элементом (касание) раскроется список со строками опций меню. Для реализации такого варианта меню создадим файл Menu1.py и напишем в нем следующий код (листинг 5.42).
Листинг 5.42. Демонстрации работы класса MDDropdownMenu (модуль Menu1.py)
# модуль Menu1.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivymd. uix. dialog import MDDialog
KV = «»»
MDScreen:
…… MDGridLayout:
…… … … cols: 1
…… … … MDRaisedButton:
…… … … … … id: button
…… … … … … text: «Открыть меню»
…… … … … … on_release: app.menu. open ()
«»»
class MainApp (MDApp):
…… def __init__ (self, **kwargs):
…… … … super ().__init__ (**kwargs)
…… … … self.screen = Builder. load_string (KV)
…… … … menu_items = [{«text»: «Меню 1»,
…… … … …… … … «viewclass»: «OneLineListItem»,
…… … … …… … … «on_release»: lambda x=«Меню 1»:
…… …… …… …… self.menu_callback (x),},
…… … … …… … … {«text»: «Меню 2»,
…… … … …… … … «viewclass»: «OneLineListItem»,
…… … … …… … … «on_release»: lambda x=«Меню 2»:
…… …… …… …… self.menu_callback (x),},
…… … … …… … … {«text»: «Меню 3»,
…… … … …… … … «viewclass»: «OneLineListItem»,
…… … … …… … … «on_release»: lambda x=«Меню 3»:
…… …… …… …… self.menu_callback (x),},]
…… … … self.menu = MDDropdownMenu(caller=self.screen.ids. button,
…… … … …… … … items=menu_items,
…… … … …… … … width_mult=3,)
…… def menu_callback (self, text_item):
…… … … dialog = MDDialog (text=«Выбрано " + text_item)
…… … … dialog. open ()
…… … … self.menu. dismiss ()
…… def build (self):
…… … … return self.screen
MainApp().run ()
В этой программе в строковой переменной KV был создан контейнер MDScreen (экран), в него вложен другой контейнер MDGridLayout (таблица с одной колонкой). В ячейку данной таблицы положили кнопку MDRaisedButton. Для этой кнопки указали идентификатор (id: button) и связали с реакцией на события нажатия — app.menu. open () — открыть меню.
На первом шаге в базовом классе MainApp в строковую переменную этого класса self.screen был загружен программный код на языке KV:
self.screen = Builder. load_string (KV)
Далее в базовом классе создали три элемента меню — menu_items. Для каждого элемента указали три свойства:
— «text»: — наименование опции меню («Меню 1»);
— «viewclass»: — класс для отображения элемента меню в списке строк («OneLineListItem»);
— «on_release»: — функция, которая обработает событие выбора данной опции меню (lambda x=«Меню 3»: self.menu_callback (x)).
В последнем свойстве указано имя вызываемой функции — self.menu_callback (x), где «x» параметр, передаваемый в функцию.
На следующем шаге был создан наш главный объект — МЕНЮ (self.menu) на основе класса MDDropdownMenu. Для этого объекта (МЕНЮ) были определены следующие параметры свойств:
— caller — вызывающий элемент «self.screen.ids. button» (в данном случае это кнопка на экране);
— items — опции (элементы) меню (menu_items);
— width_mult — ширина строки, на которой размещены опции меню (3).
В следующих строках программы определена функция, которая обрабатывает событие выбора той или иной опции меню (def menu_callback). Эта функция принимает название выбранной опции меню (text_item), выводит этот текст в диалоговое окно и, после закрытия диалогового окна, убирает с экрана развернутый список опций меню.
Наконец, в базовом классе определена функция вызова (построения) основного экрана — def build. Эта функция запускает в работу код на языке KV, который мы загрузили в строковую переменную self.screen в первых строках кода базового класса приложения.
Итак, мы создали простейшее меню с тремя опциями и функцией обработки событий выбора той или иной опции меню. После запуска данного приложения получим следующий результат (рис.5.55).
Рис. 5.55. Результат выполнения приложения из модуля Menu1.py
Как видно из данного рисунка (окно слева), после запуска приложения на экране появилась кнопка, касанием которой можно открыть меню. В окне (центр рисунка) показан экран с открытыми опциями меню. После выбора одной из опций управление передается функции, которая обрабатывает события касания строк списка с опциями меню. Результаты работы этой функции показана на данном рисунке (окно справа).
5.19.2. MDDropdownMenu — класс для создания выпадающих строковых меню с иконкой
В этом случае на экране располагается элемент (кнопка, надпись), который занимает на экране мало места, но при взаимодействии с этим элементом (касание) раскроется список со строками опций меню. При этом в строке кроме текста будет присутствовать и иконка. Для реализации такого варианта меню создадим файл Menu2.py и напишем в нем следующий код (листинг 5.43).
Листинг 5.43. Демонстрации работы класса MDDropdownMenu (модуль Menu2.py)
# модуль Menu2.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivymd. uix. dialog import MDDialog
from kivymd.uix.list import OneLineIconListItem
from kivy.properties import StringProperty
KV = «»»
<IconListItem>
…… IconLeftWidget:
…… icon: root. icon
…… MDScreen:
…… …… MDGridLayout:
…… …… …… cols: 1
…… …… …… MDRaisedButton:
…… …… …… …… id: button
…… …… …… …… text: «Открыть меню»
…… …… …… …… on_release: app.menu. open ()
«»»
class IconListItem (OneLineIconListItem):
…… icon = StringProperty ()
class MainApp (MDApp):
…… def __init__ (self, **kwargs):
…… …… super ().__init__ (**kwargs)
…… …… self.screen = Builder. load_string (KV)
…… …… menu_items = [{«text»: «Кондиционер»,
…… …… …… «icon»: «air-conditioner»,
…… …… …… «viewclass»: «IconListItem»,
…… …… …… «on_release»: lambda x=«Меню 1»: self.menu_callback (x),},
…… …… …… {«text»: «Фильтр»,
…… …… …… «icon»: «air-filter»,
…… …… …… «viewclass»: «IconListItem»,
…… …… …… «on_release»: lambda x=«Меню 2»: self.menu_callback (x),},
…… …… …… {«text»: «Насос»,
…… …… …… «icon»: «air-purifier»,
…… …… …… «viewclass»: «IconListItem»,
…… …… …… «on_release»: lambda x=«Меню 3»: self.menu_callback (x),},]
…… … … self.menu = MDDropdownMenu(caller=self.screen.ids. button,
…… …… …… items=menu_items,
…… …… …… width_mult=3.1,)
…… def menu_callback (self, text_item):
…… … … print (text_item)
…… … … dialog = MDDialog (text=«Выбрано " + text_item)
…… … … dialog. open ()
…… … … self.menu. dismiss ()
…… def build (self):
…… … … return self.screen
MainApp().run ()
Эта программа аналогична той, которая представлена в предыдущем листинге. В него внесены следующие изменения. Добавлен класс IconListItem (элементы списка с иконками) на основе класса OneLineIconListItem. В строковой переменной KV создан контейнер IconListItem (элементы списка с иконками), в него положен виджет IconLeftWidget и свойству icon присвоено значение иконки из базового класса (icon: root. icon). И, наконец, к элементам меню menu_items свойству icon добавлено имя иконки (например, «air-filter»), и изменено свойство viewclass — ему присвоено значение «IconListItem». После запуска данного приложения получим следующий результат (рис.5.56).
Рис. 5.56. Результат выполнения приложения из модуля Menu2.py
5.19.3. MDDropdownMenu — класс для создания меню в верхней панели MDToolbar
В мобильных устройствах наиболее часто встречаются приложения, у которых меню расположено в верхней панели, для KivyMD это панель MDToolbar. Это некий аналог меню приложений, которые работают на персональных компьютерах. То есть на экране постоянно присутствует верхняя панель с элементами меню, а вся остальная часть экрана используется для элементов интерфейса пользователя.
Для реализации такого варианта меню создадим файл Menu3.py и напишем в нем следующий код (листинг 5.44).
Листинг 5.44. Демонстрации работы класса MDDropdownMenu (модуль Menu3.py)
# модуль Menu3.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.snackbar import Snackbar
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… … … title: «Меню в MDToolbar»
…… … … left_action_items: [[«menu», lambda x: app.callback (x)]]
…… … … right_action_items: [[«dots-vertical», lambda x: app.callback_r (x)]]
…… MDLabel:
…… … … text: «Основное окно приложения»
…… … … halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… … … # опции меню левой кнопки
…… … … menu_items = [{«text»: «Меню левое 1»,
…… … …… … «viewclass»: «OneLineListItem»,
…… … ….. … «on_release»: lambda x=«Меню левое 1»: self.menu_callback (x),},
…… … …… … {«text»: «Меню левое 2»,
…… … …… … «viewclass»: «OneLineListItem»,
…… … …… … «on_release»: lambda x=«Меню левое 2»: self.menu_callback (x),},
…… … … … … {«text»: «Меню левое 3»,
…… … …… … «viewclass»: «OneLineListItem»,
…… … … … …«on_release»: lambda x=«Меню левое 3»:
…… …… … … self.menu_callback (x),},]
…… … … self.menu = MDDropdownMenu (items=menu_items, width_mult=2.5,)
…… … … # опции меню правой кнопки
…… … … menu_items_r = [{«text»: «Меню правое 1»,
…… …… … … «viewclass»: «OneLineListItem»,
…… …… … … «on_release»: lambda x=«Меню правое 1»:
…… …… … … self.menu_callback_r (x),},
…… …… … … {«text»: «Меню правое 2»,
…… …… … … «viewclass»: «OneLineListItem»,
…… …… … … «on_release»: lambda x=«Меню правое 2»:
…… …… … … self.menu_callback_r (x),},
…… …… … … {«text»: «Меню правое 3»,
…… …… … … «viewclass»: «OneLineListItem»,
…… …… … … «on_release»: lambda x=«Меню правое 3»:
…… …… … … self.menu_callback_r (x),},]
…… … … self.menu_r = MDDropdownMenu
…… … … …… … … (items=menu_items_r, width_mult=2.5,)
…...return Builder. load_string (KV)
…… # Открыть левое меню ##################
…… def callback (self, button):
…… … … self.menu.caller = button
…… … … self.menu. open ()
…… # Обработка событий левого меню #######
…… def menu_callback (self, text_item):
…… … … self.menu. dismiss ()
…… … … Snackbar (text=text_item).open ()
…… # Открыть правое меню #################
…… def callback_r (self, button):
…… … … self.menu_r.caller = button
…… … … self.menu_r. open ()
…… # Обработка событий правого меню #######
…… def menu_callback_r (self, text_item):
…… … … self.menu_r. dismiss ()
…… … … Snackbar (text=text_item).open ()
MainApp().run ()
В этой программе в строковой переменной KV был создан контейнер MDBoxLayout с вертикальной ориентацией. В него вложено два элемента: верхняя панель — MDToolbar, и метка MDLabel. В свою очередь в MDToolbar вложено три элемента:
— title: — заголовок («Меню в MDToolbar»);
— left_action_items: — левая иконка в виде тройной полосы («menu»), и функция, которая будет вызвана при касании иконки «lambda x: app.callback (x)»;
— right_action_items: — правая иконка в виде тройных точек («dots-vertical»), и функция, которая будет вызвана при касании иконки «lambda x: app.callback_r (x)».
Далее следует программный код, который уже знаком по предыдущим листингам. Отличие заключается лишь в том, что здесь создается два списка опций меню: для левой кнопки в MDToolbar (menu_items), и для правой кнопки (menu_items_r). А также два объекта меню: self.menu — левой кнопки в MDToolbar, и self.menu_r — для правой кнопки. Также созданы две пары функций:
— def callback — для открытия списка опций левого меню, def menu_callback для обработки событий выбора опции левого меню;
— def callback_r — для открытия списка опций правого меню, def menu_callback_r для обработки событий выбора опции правого меню.
Для демонстрации результатов выбора той или иной опции меню в функциях обработки событий касания экрана используется объект Snackbar (нижняя временная информационная панель), на которую выводится выбранная пользователем опция меню. После запуска данного приложения получим следующий результат (рис.5.57).
Рис. 5.57. Результат выполнения приложения из модуля Menu3.py
5.19.4. MDDropdownMenu — класс для создания меню из текстового поля
В KivyMD можно создать меню из поля для ввода текста. То есть на экране присутствует текстовое поле, при касании которого появляется выпадающее меню. Результаты выбора возвращаются в поле для ввода текста. Для реализации такого варианта меню создадим файл Menu4.py и напишем в нем следующий код (листинг 5.45).
Листинг 5.45. Демонстрации работы класса MDDropdownMenu (модуль Menu4.py)
# модуль Menu4.py
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty
from kivymd.uix.list import OneLineIconListItem
from kivymd. app import MDApp
from kivymd.uix.menu import MDDropdownMenu
KV = «»»
<IconListItem>
…… IconLeftWidget:
…… …… icon: root. icon
MDScreen
…… MDTextField:
…… …… id: field
…… …… i pos_hint: {’center_x’:.35, ’center_y’:.7}
…… …… i size_hint_x: None
…… …… i width: «200dp»
…… …… i hint_text: «Выбор адреса»
…… …… i on_focus: if self.focus: app.menu. open ()
«»»
class IconListItem (OneLineIconListItem):
…… icon = StringProperty ()
class MainApp (MDApp):
…… def __init__ (self, **kwargs):
…… … … super ().__init__ (**kwargs)
…… … … self.screen = Builder. load_string (KV)
…… … … menu_items = [{«viewclass»: «IconListItem»,
…… … … …… … … «icon»: «email»,
…… … … …… … … «height»: dp (36),
…… … … …… … … «text»: "soft_1@mail.ru»,
…… … … …… … … «on_release»: lambda x="soft_1@mail.ru»:
…… …… …… …… self.set_item (x),},
…… … … …… … … {«viewclass»: «IconListItem»,
…… … … …… … … «icon»: «email»,
…… … … …… … … «height»: dp (36),
…… … … …… … … «text»: "soft_2@mail.ru»,
…… … … …… … … «on_release»: lambda x="soft_2@mail.ru»:
…… …… …… …… self.set_item (x),},
…… … … …… … … {«viewclass»: «IconListItem»,
…… … … …… … … «icon»: «email»,
…… … … …… … … «height»: dp (36),
…… … … …… … … «text»: "soft_3@mail.ru»,
…… … … …… … … «on_release»: lambda x="soft_3@mail.ru»:
…… …… …… …… self.set_item (x),}]
…… … … self.menu = MDDropdownMenu(caller=self.screen.ids.field,
…… … … …… … … items=menu_items,
…… … … …… … … position=«bottom»,
…… … … …… … … # position=«center»,
…… … … …… … … width_mult=3.5,)
…… def set_item (self, text__item):
…… …… self.screen.ids.field. text = text__item
…… …… self.menu. dismiss ()
…… def build (self):
…… …… return self.screen
MainApp().run ()
Не будем разбирать детали структуры этого программного кода, поскольку они достаточно подробно описана при анализе предыдущих листингов программ реализации меню, а остановимся лишь на некоторых особенностях:
— Опции меню вызываются из строки для ввода текста.
— Каждая опция меню снабжена иконкой, на касание которой можно возложить выполнение каких либо действий.
— Опции меню могут открыться либо под текстовой строкой, либо по центру этой строки.
Где откроется поле с опциями меню, зависит от значения свойства меню — position:
— position=«bottom» — опции меню откроются под текстовой строкой;
— position=«center» — опции меню откроются по центру текстовой строки.
В приведенном выше листинге строка # position=«center» закомментирована. Сняв с нее комментарий можно изменить положение поля с опциями меню.
После запуска данного приложения получим следующий результат (рис.5.58).
Рис. 5.58. Результат выполнения приложения из модуля Menu4.py
5.20. Navigation Drawer — класс для создания выдвижной навигационной панели
Класс MDNavigationDrawer позволяет создать в мобильном приложении выдвижную навигационную панель. Навигационную панель рекомендуются создавать в тех случаях, когда необходимо осуществлять быстрый переход между различными функциональными блоками приложения. На этой панели можно разместить элементы, которые обеспечат доступ к различным функциям приложения, например можно осуществить быстрое переключение между окнами приложения на экране мобильного устройства.
При создании выдвижной навигационной панели строится дерево виждетов (на языке KV), которое имеет следующую структуру (рис.5.59).
Рис. 5.59. Структура дерева виджетов при использовании выдвижной навигационной панели
Основой (корнем) этого дерева является корневой виджет, на приведенном выше рисунке это Screen (экран). В корневой виджет вложен контейнер MDNavigationLayout, в котором находятся все остальные элементы интерфейса. Это, по сути, ствол дерева виджетов, который разделяется на две главные ветки:
— ScreenManager — менеджер экранов;
— MDNavigationDrawer — навигационная панель.
Менеджер экранов представляет собой контейнер, с вложенными в него экранами приложения. Каждый экран представляет собой самостоятельный элемент со своим набором виджетов. Менеджер экранов взаимодействует с элементами навигационной панели и обеспечивает смену экранов.
Навигационная панель, которая выплывает на основное окно приложения, также является контейнером, в котором находится элемент ContentNavigationDrawer (содержимое навигационной панели). Этот элемент так же является контейнером, в который вкладываются виджеты навигационной панели. Это видимые виджеты, с которыми взаимодействует пользователь. Через них он и управляет сменой экранов в главном окне приложения.
Рассмотрим реализацию данной структуры на простом примере, пока создав пустую навигационную панель. Для этого создадим файл NaviDrawer1.py и напишем в нем следующий код (листинг 5.46).
Листинг 5.46. Демонстрации работы класса MDNavigationDrawer (модуль NaviDrawer1.py)
# модуль NaviDraver1.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
# корневой контейнер
Screen:
…… # контейнер для размещения элементов навигации
…… MDNavigationLayout:
…… … … # менеджер экранов
…… … … ScreenManager:
…… … … # экран приложения
…… … … Screen:
…… …… … … # контейнер для размещения виджетов
…… …… … … BoxLayout:
…… …… …… … … orientation: ’vertical’
…… …… …… … … # верхняя панель
…… …… …… … … MDToolbar:
………… …… …… … … title: «Навигационная панель»
.. ……… …… …… … … elevation: 10
.. ……… …… …… … … left_action_items: [[’menu’, lambda x:
…….. ……… …… …… … … nav_drawer.set_state («open»)]]
.. ……… …… …… … … Widget:
…… …… …… … … # выдвижная навигационная панель
…… …… …… … … MDNavigationDrawer:
…… …… …… …… … … id: nav_drawer
…… …… …… …… … … # контейнер для виджетов
…… …… …… …… … … MDFloatLayout:
…… … … …… …… …… … … #…элемент 1…#
…… … … …… …… …… … … #…элемент 2…#
…… … …… …… …… … … … #элемент N…#
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В данном приложении в строковой переменной KV реализовано следующее дерево виджетов. Создан корневой контейнер Screen (экран), в который положили следующий контейнер MDNavigationLayout (навигационный планировщик). В этот контейнер вложено два элемента ScreenManager (менеджер экранов) и MDNavigationDrawer (это и есть наша навигационная панель). В навигационной панели находится контейнер для размещения виджетов (MDFloatLayout), в котором пока нет никаких элементов.
В свою очередь в контейнер ScreenManager последовательно вложены элементы (один в другой): Screen (экран), BoxLayout (контейнер для виджетов с вертикальной ориентацией). В последний контейнер вложена верхняя панель (MDToolbar) со своими параметрами и Widget (визуальные элементы, пока этот контейнер пуст).
После запуска данного приложения получим следующий результат (рис.5.60).
Рис. 5.60. Результат выполнения приложения из модуля NaviDrawer1.py
После запуска приложения на экране появляется главное окно приложения, в верхней части которого находится панель инструментов с одной кнопкой. При касании этой кнопки с левой стороны окна вдвинется навигационная панель. Пока она пустая, поскольку мы не разместили на ней никаких элементов. Если коснуться любой части основного окна приложения, то навигационная панель скроется и экран вернется к первоначальному виду.
Немного модернизируем программный код, приведенный выше, На навигационную панель добавим несколько виждетов, чтобы они отобразились на выплывающей панели. Для этого создадим файл NaviDrawer2.py и напишем в нем следующий код (листинг 5.47).
Листинг 5.47. Демонстрации работы класса MDNavigationDrawer (модуль NaviDrawer2.py)
# модуль NaviDraver2.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
Screen:
…… MDNavigationLayout:
…… …… ScreenManager:
…… …… …… Screen:
…… …… …… …… BoxLayout:
…… …… …… …… …… orientation: ’vertical’
…… …… …… …… …… MDToolbar:
…… …… …… …… …… …… title: «Навигационная панель»
.. … …… …… …… …… …… elevation: 10
.. … …… …… …… …… …… left_action_items:
.. … …… …… …… …… … … … [[’menu’, lambda x: nav_drawer.set_state («open»)]]
…… …… …… …… …… Widget:
…… …… MDNavigationDrawer:
…… …… …… id: nav_drawer
…… …… …… # Здесь будет отображаться содержимое панели
…… …… …… MDScreen:
…… …… …… …… MDFloatLayout:
…… …… …… …… …… MDLabel:
…… …… …… …… …… …… text: «Заголовок»
…… …… …… …… …… …… pos_hint: {«center_x»:. 8, «center_y»:. 9}
…… …… …… …… …… MDLabel:
…… …… …… …… …… …… text: «Контент 1»
…… …… …… …… …… …… pos_hint: {«center_x»:. 55, «center_y»:. 8}
…… …… …… …… …… MDLabel:
…… …… …… …… …… …… text: «Контент 2»
…… …… …… …… …… …… pos_hint: {«center_x»:. 55, «center_y»:. 7}
…… …… …… …… …… MDLabel:
…… …… …… …… …… …… text: «Контент 3»
…… …… …… …… …… …… pos_hint: {«center_x»:. 55, «center_y»:. 6}
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этой программе в выдвижную навигационную панель вложили экран (MDScreen), на него поместили контейнер (MDFloatLayout), и уже в нем создали 3 метки (MDLabel) со своим набором свойств. После запуска данного приложения получим следующий результат (рис.5.61).
Рис. 5.61. Результат выполнения приложения из модуля NaviDrawer2.py
Если запустить приложение и коснуться левой иконки в верхней строке с элементом MDToolbar, то на экран вдвинется навигационная панель, с размещенными на ней элементами интерфейса. Если касаться этих элементов, то ничего не произойдет, поскольку мы еще не реализовали функции для обработки событий. Теперь можно еще модифицировать программный код, добавив в него обработку событий.
Для этого создадим файл NaviDrawer3.py и напишем в нем следующий код (листинг 5.48).
Листинг 5.48. Демонстрации работы класса MDNavigationDrawer (модуль NaviDrawer3.py)
# модуль NaviDraver3.py
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd. app import MDApp
KV = «»»
# Это содержимое навигационной панели
<ContentNavigationDrawer>:
…… ScrollView:
…… … … MDList:
…… … … … … OneLineListItem:
…… …… … … … … text: «Экран 1»
…… …… … … … … on_press:
…… …… … … … … root.nav_drawer.set_state («close»)
…… …… … … … … root.screen_manager.current = «scr 1»
…… … … … … OneLineListItem:
…… …… … … … … text: «Экран 2»
…… …… … … … … on_press:
…… …… … … … … root.nav_drawer.set_state («close»)
…… …… … … … … root.screen_manager.current = «scr 2»
…… … … … … OneLineListItem:
…… …… … … … … text: «Экран 3»
…… …… … … … … on_press:
…… …… … … … … root.nav_drawer.set_state («close»)
…… …… … … … … root.screen_manager.current = «scr 3»
#Это содержимое основного экрана приложения
Screen:
…… MDToolbar:
…… … … id: toolbar
…… … … pos_hint: {«top»: 1}
…… … … elevation: 10
…… … … title: «MDNavigationDrawer»
…… … … left_action_items: [[«menu», lambda x:
…… … … … … … … nav_drawer.set_state («open»)]]
…… MDNavigationLayout:
…… …… x: toolbar. height
…… …… ScreenManager:
…… …… …… id: screen_manager
…… …… …… # Это содержимое экрана 1
…… …… …… Screen:
…… …… …… …… name: «scr 1»
…… …… …… …… MDLabel:
…… … …… …… ……… text: «Открыт экран 1»
…… … …… …… ……… halign: «center»
…… …… …… # Это содержимое экрана 2
…… …… …… Screen:
…… …… …… …… name: «scr 2»
…… …… …… …… MDLabel:
…… … …… …… ……… text: «Открыт экран 2»
…… … …… …… ……… halign: «center»
…… …… …… # Это содержимое экрана 3
…… …… …… Screen:
…… …… …… …… name: «scr 3»
…… …… …… …… MDLabel:
…… … …… …… ……… text: «Открыт экран 3»
…… … …… …… ……… halign: «center»
…… …… MDNavigationDrawer:
…… …… …… id: nav_drawer
…… …… …… ContentNavigationDrawer:
…… … … …… …… screen_manager: screen_manager
…… …… …… …… nav_drawer: nav_drawer
«»»
class ContentNavigationDrawer (BoxLayout):
…… screen_manager = ObjectProperty ()
…… nav_drawer = ObjectProperty ()
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В этой программе был создан новый дополнительный класс ContentNavigationDrawer (контент навигационной панели) на основе базового класса BoxLayout. В нем создано два объекта на основе ObjectProperty ():
— screen_manager — менеджер экранов;
— nav_drawer — навигационная панель.
В строковой переменной KV находятся два корневых виджета:
— для выдвижной навигационной панели (<ContentNavigationDrawer>:);
— для основного экран приложения (Screen).
На выдвижной панели находится контейнер ScrollView (для скроллинга элементов, если они не будут помещаться в экран), и список элементов (MDList). В этом списке три элемента (OneLineListItem) с аналогичными по смыслу свойствами:
— text: — текст в строке («Экран 1», «Экран 2», «Экран 3»);
— on_press: — функции для обработки событий касания строки.
При касании этих элементов буде выполнено обращение к двум функциям:
— root.nav_drawer.set_state («close») — закрыть (задвинуть) навигационную панель;
— root.screen_manager.current — обратиться к менеджеру экранов и отобразить в главном окне приложения экран с соответствующим идентификатором («scr 1», «scr 1», «scr 1»).
Идентификаторы экранов описаны в следующем блоке строковой переменной KV ((Screen)), рассмотрим его более подробно.
Содержимое основного экрана приложения начинается с контейнера Screen (экран), в котором размещено два элемента:
— MDToolbar: — верхняя панель с иконкой (кнопкой);
— MDNavigationLayout: — контейнер для размещения навигационной панели.
В контейнере навигационной панели находятся:
— ScreenManager: — менеджер экранов;
— MDNavigationDrawer — контейнер для размещения элементов навигационной панели.
Менеджер экранов управляет тремя сменяемыми экранами (Screen) с идентификаторами: «scr 1», «scr 2», «scr 3». Каждый экран имеет свой набор отображаемых элементов.
Контейнер для размещения элементов навигационной панели (MDNavigationDrawer) содержит контент, который был описан выше в блоке <ContentNavigationDrawer>. Управление этим контентом осуществляется с помощью менеджера экранов (screen_manager) и nav_drawer.
На первый взгляд структура приложения достаточно сложная, но достаточно эффективная в работе. После запуска данного приложения получим следующий результат (рис.5.62).
Рис. 5.62. Результат выполнения приложения из модуля NaviDrawer3.py
Из данного рисунка видно, что при старте приложения в главном окне отображаются элементы экрана 1. После активации навигационной панели и касания в ней опции Экрана 2, навигационная панель исчезает, и в главном окне приложения отображаются элементы, размещенные на втором экране. Таким образом, с использованием навигационной панели можно достаточно просто менять экраны в главном окне приложения.
На выдвижной панели можно размещать иконки или изображения. Текстовую строку можно совместить с иконкой, при этом можно перехватить и обработать такие события, как касание строки, так и касания иконки. Для демонстрации такой возможности создадим файл NaviDrawer4.py и напишем в нем следующий код (листинг 5.49).
Листинг 5.49. Демонстрации работы класса MDNavigationDrawer (модуль NaviDrawer4.py)
# модуль NaviDraver4.py
from kivy.lang import Builder
from kivy.properties import StringProperty, ListProperty
from kivymd. app import MDApp
from kivymd.theming import ThemableBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.list import OneLineIconListItem, MDList
KV = «»»
# Пункты меню в выдвижной панели.
<ItemDrawer>:
…… theme_text_color: «Custom»
…… on_release: self.parent.set_color_item (self)
…… IconLeftWidget:
…… …… id: icon
…… …… icon: root. icon
…… …… theme_text_color: «Custom»
…… …… text_color: root. text_color
# Содержимое выдвижной панели
<ContentNavigationDrawer>:
…… orientation: «vertical»
…… padding: «8dp»
…… spacing: «8dp»
…… AnchorLayout:
…… … … anchor_x: «left»
…… … … size_hint_y: None
…… … … height: avatar. height
…… … … Image:
…… …… … … id: avatar
…… …… … … size_hint: None, None
…… …… … … size: «56dp», «56dp»
…… …… … … source: "./Images/kivymd.jpg»
…… …… … … #source: "data/logo/kivy-icon-256.png»
…… MDLabel:
…… …… text: «Библиотека KivyMD»
…… …… #font_style: «Button»
…… …… adaptive_height: True
…… MDLabel:
…… …… text: "https://kivymd.readthedocs.io/en/0.104.2/"
…… …… font_style: «Caption»
…… …… adaptive_height: True
…… ScrollView:
…… …… DrawerList:
…… …… …… id: md_list
# Содержимое главного экрана
MDScreen:
…… MDNavigationLayout:
…… …… ScreenManager:
…… …… …… MDScreen:
…… …… …… …… MDBoxLayout:
…… …… …… …… …… orientation: ’vertical’
…… …… …… …… …… MDToolbar:
…… …… …… …… …… …… title: «Выдвижная панель»
……… … …… …… …… …… elevation: 10
…… …… …… …… …… …… left_action_items: [[’menu’, lambda x:
…… …… …… …… …… …… …… …… nav_drawer.set_state («open»)]]
…… …… …… …… Widget:
…… …… MDNavigationDrawer:
…… …… …… id: nav_drawer
…… …… …… ContentNavigationDrawer:
…… … …… …… id: content_drawer
«»»
class ContentNavigationDrawer (MDBoxLayout):
…… pass
class ItemDrawer (OneLineIconListItem):
…… icon = StringProperty ()
…… text_color = ListProperty ((0, 0, 0, 1))
class DrawerList (ThemableBehavior, MDList):
…… def set_color_item (self, instance_item):
…… …… «„«Вызывается при касании элемента панели»»»
…… …… # Задает цвет иконки и текста элемента панели
…… …… for item in self.children:
…… …… …… if item. text_color == self.theme_cls.primary_color:
…… … … …… …… item. text_color = self.theme_cls. text_color
…… … … …… …… break
…… …… instance_item. text_color = self.theme_cls.primary_color
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_start (self):
…… …… icons_item = {«folder»: «Мои файлы»,
…… …… …… …… «music-box»: «Музыка»,
…… …… …… …… «phone-classic»: «Телефоны»,
…… …… …… …… «folder-image»: «Изображения»,
…… …… …… …… «email»: «Адреса»,
…… …… …… …… «folder-text»: «Документы», }
…… …… for icon_name in icons_item.keys ():
…… …… …… …… self.root.ids.content_drawer.ids.md_list.add_widget (
…… …… …… …… ItemDrawer (icon=icon_name, text=icons_item [icon_name]))
MainApp().run ()
Структура этого программного кода аналогична программам, которые приведенных в предыдущих листингах программ данного раздела. Поэтому не будем делать подробного разбора этого кода, а упомянем только о дополнительных компонентах.
— В головном модуле добавлена функция def on_start, в которой создан список иконок и подписей к ним (этот список будет отображаться в выдвижной панели).
— Добавлен класс ItemDrawer на основе базового класса OneLineIconListItem (однострочный элемент с иконкой).
— Добавлен класс DrawerList для обработки события касания элемента списка в выдвигающейся панели (изменяет цвет строки, к которой прикоснулся пользователь).
После запуска данного приложения получим следующий результат (рис.5.63).
Рис. 5.63.
Результат выполнения приложения из модуля NaviDrawer4.py
Из данного рисунка видно, что после активации навигационной панели в верхней ее части появился рисунок и заголовок. Ниже находится список элементов панели (иконка и надпись). Каждая строка этого списка реагирует на касания, как надписи, так и иконки (это два разных события и их можно обработать в разных функциях). Если коснуться только иконки, то она отреагирует на касание мерцанием (функцию обработки данного события в данном модуле мы не создавали). Если коснуться строки списка, то она станет синего цвета (отработает функция обработки этого события — DrawerList).
Приведенные в данном разделе программные модули можно использовать как шаблоны для создания окон в своих приложениях.
5.21. MDNavigation Rail — класс для создания навигационной рейки
Класс MDNavigationRail — это боковой компонент для размещения элементов навигации. Он позволяет отобразить список элементов, при взаимодействии с которыми можно перейти в различные разделы приложения. Каждый такой элемент представлен иконкой и текстовой меткой. В дереве виджетов этот компонент имеет следующую структуру:
MDNavigationRail:
MDNavigationRailItem:
MDNavigationRailItem:
MDNavigationRailItem:
Рассмотрим реализацию данной структуры на простом примере. Для этого создадим файл NaviRail_1.py и напишем в нем следующий код (листинг 5.50).
Листинг 5.50. Демонстрации работы класса MDNavigationRail (модуль NaviRail_1.py)
# модуль NaviRail_1.py
from kivy. factory import Factory
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. dialog import MDDialog
KV = «»»
#:import get_color_from_hex kivy.utils.get_color_from_hex
<MyTile@SmartTileWithStar>
…… size_hint_y: None
…… size_hint_x: None
…… # height: «140dp»
…… MDBoxLayout:
…… …… orientation: «vertical»
…… …… MDToolbar:
…… …… …… title: «Навигационнная рейка»
…… …… …… md_bg_color: rail.md_bg_color
…… …… MDBoxLayout:
…… …… …… #навигационная рейка
…… …… …… MDNavigationRail:
…… …… …… …… id: rail
…… …… …… …… md_bg_color: get_color_from_hex («#344954»)
…… …… …… …… color_normal: get_color_from_hex («#718089»)
…… …… …… …… color_active: get_color_from_hex («#f3ab44»)
…… …… …… …… #элементы навигационной рейки
…… …… …… …… MDNavigationRailItem:
…… …… …… …… …… icon: «language-cpp»
…… …… …… …… …… text: «C++»
…… …… …… …… …… on_press: app.press_icon («C++»)
…… …… …… …… MDNavigationRailItem:
…… …… …… …… …… icon: «language-python»
…… …… …… …… …… text: «Python»
…… …… …… …… …… on_press: app.press_icon («Python»)
…… …… …… …… MDNavigationRailItem:
…… …… …… …… …… icon: «language-swift»
…… …… …… …… …… text: «Swift»
…… …… …… …… …… on_press: app.press_icon («Swift»)
…… …… …… MDBoxLayout:
…… …… …… …… padding: «5dp»
…… …… …… …… ScrollView:
…… …… …… …… …… MDList:
…… …… …… …… …… …… id: box
…… …… …… …… …… …… cols: 2
…… …… …… …… …… …… spacing: «5dp»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_start (self):
…… …… for i in range (8):
…… …… …… tile = Factory.MyTile(source="./Images/kivymd.jpg»)
…… …… …… tile.stars = 2
…… …… …… self.root.ids.box.add_widget (tile)
…… def press_icon (self, text_item):
…… …… dialog = MDDialog (text=«Выбрано " + text_item)
…… …… dialog. open ()
MainApp().run ()
В данном приложении в базовом классе в функции on_start создан объект tile (плитка, панель), в который загрузили изображение (эмблема KivyMD) и создан виджет — контейнер box, в который положили 8 этих изображений. Кроме того, создана дополнительная функция, в которой обрабатывается событие касания иконок, находящихся в навигационной рейке.
В переменной KV создали контейнер MDBoxLayout, в который поместили верхнюю панель MDToolbar и еще один контейнер MDBoxLayout. В последнем контейнере создали навигационную рейку MDNavigationRail с тремя иконками, и еще один контейнер MDBoxLayout. Наконец, в последнем контейнере находится элемент, который обеспечивает скроллинг (ScrollView) и список из двух колонок, в который вложено 8 элементов с рисунком. После запуска данного приложения получим следующий результат (рис.5.64).
Рис. 5.64.
Результат выполнения приложения из модуля NaviRail_1.py
Из данного рисунка видно, что после запуска приложения в левой части окна имеется навигационная рейка со списком иконок. Каждая строка этого списка реагирует на касание, и обработка этого события осуществляется в функции def press_icon. В оставшейся части окна находятся 8 изображений. Они не все вошли в экран, но, с использованием скроллинга, можно переместить в видимую часть окна любое из этих восьми изображений. При касании любого из изображений по нему пробегает рябь. Это говорит о том, каждый элемент основного экрана реагирует на касания, значит можно создать функцию обработки этих событий.
Навигационную рейку можно сузить до размера иконки, при этом она имеет возможность расширяться с показом сопроводительного текста. Для демонстрации этой возможности создадим файл NaviRail_2.py и напишем в нем следующий код (листинг 5.51).
Листинг 5.51. Демонстрации работы класса MDNavigationRail (модуль NaviRail_2.py)
# модуль NaviRail_2.py
from kivy. factory import Factory
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
#:import get_color_from_hex kivy.utils.get_color_from_hex
<MyTile@SmartTileWithLabel>
…… size_hint_y: None
…… size_hint_x: None
…… #height: «120dp»
…… text:» [size=10] Шарик [/size]»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… title: «Навигационнная рейка»
…… …… md_bg_color: rail.md_bg_color
…… …… left_action_items: [[«menu», lambda x: app. rail_open ()]]
…… …… MDBoxLayout:
…… …… …… MDNavigationRail:
…… …… …… …… id: rail
…… …… …… …… md_bg_color: get_color_from_hex («#344954»)
…… …… …… …… color_normal: get_color_from_hex («#718089»)
…… …… …… …… color_active: get_color_from_hex («#f3ab44»)
…… …… …… …… use_resizeable: True
…… …… …… MDNavigationRailItem:
…… …… …… …… icon: «language-cpp»
…… …… …… …… text: «C++»
…… …… …… MDNavigationRailItem:
…… …… …… …… icon: «language-java»
…… …… …… …… text: «Java»
…… …… …… MDNavigationRailItem:
…… …… …… …… icon: «language-swift»
…… …… …… …… text: «Swift»
…… …… …… MDBoxLayout:
…… …… …… …… padding: «24dp»
…… …… …… …… ScrollView:
…… … … …… …… …… MDList:
…… …… … … …… …… …… id: box
…… …… … … …… …… …… cols: 2
…… …… … … …… …… …… spacing: «12dp»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def rail_open (self):
…… …… if self.root.ids. rail. rail_state == «open»:
…… …… …… self.root.ids. rail. rail_state = «close»
…… …… else:
…… …… …… self.root.ids. rail. rail_state = «open»
…… def on_start (self):
…… …… for i in range (4):
…… …… …… tile = Factory.MyTile(source="./Images/Dog.jpg»)
…… …… …… self.root.ids.box.add_widget (tile)
MainApp().run ()
По сравнению с листингом предыдущего модуля здесь были сделаны следующие изменения:
— в верхнюю панель MDToolbar добавлена иконка «меню» (в виде 3-х строчек);
— событие касания иконки «меню» связали с функцией app. rail_open;
— в базовом модуле создали функцию app. rail_open, которая обрабатывает событие касания иконки «меню».
После запуска данного приложения получим следующий результат (рис.5.65).
Рис. 5.65. Результат выполнения приложения из модуля NaviRail_2.py
Как видно из данного рисунка, после касания иконки «меню» на верхней панели боковая рейка расширяется. При повторном касании иконки окно принимает первоначальный вид.
5.22. Pickers (сборщик) — класс для создания сборной панели выбора даты и времени
В KivyMD предоставлены следующие классы для создания сборных панелей:
— MDTimePicker — панель для задания времени;
— MDDatePicker — панель для задания даты;
— MDThemePicker — панель для смены темы интерфейса приложения.
6.22.1. MDTimePicker — панель для задания времени
Рассмотрим реализацию панели для выбора и задания времени на простом примере. Для этого создадим файл MDTimePicker1.py и напишем в нем следующий код (листинг 5.52).
Листинг 5.52. Демонстрации работы класса MDTimePicker (модуль MDTimePicker1.py)
# модуль MDTimePicker1.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. picker import MDTimePicker
from datetime import datetime
KV = «»»
MDFloatLayout:
…… MDRaisedButton:
…… …… text: «Открыть Time Picker»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.6}
…… …… on_release: app.show_time_picker ()
…… MDLabel:
…… …… id: time_label
…… …… text: «Итоги выбора времени!»
…… …… halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… # self.theme_cls.theme_style = «Light»
…… …… # self.theme_cls.primary_palette = «BlueGray»
…… …… return Builder. load_string (KV)
…… # функция открытия диалогового окна
…… def show_time_picker (self):
…… …… # Задать время по умолчанию
…… …… default_time = datetime.strptime («12:00:00»,
…… …… '%H:%M:%S»).time ()
…… …… # создать объект time_dialog
…… …… time_dialog = MDTimePicker ()
…… …… # Связать time_dialog с функциями обработки событий
…… …… time_dialog.bind (on_cancel=self. on_cancel,
…… …… …… …… …… …… …… …… …… time=self.get_time)
…… …… # Задать время по умолчанию
…… …… time_dialog.set_time (default_time)
…… …… # открыть диалоговое окно
…… …… time_dialog. open ()
…… # Получить время
…… def get_time (self, instance, time):
…… …… self.root.ids. time_label. text = str (time)
…… # Нажато — Cancel
…… def on_cancel (self, instance, time):
…… …… self.root.ids. time_label. text = «Вы Нажали Cancel!»
MainApp().run ()
В данном приложении на языке разметки в строковой переменной KV создано два элемента:
— MDRaisedButton — кнопка, при нажатии на которую выполнится обращение к функции show_time_picker, где обеспечивается создание и открытие диалогового окна с элементом MDTimePicker;
— MDLabel — метка, в которую вернется и отобразится значение времени, выбранное пользователем.
В базовом классе имеется две функции:
— def get_time — для обработки события get_time (получить выбранное время) и передачи этого значения метке time_label;
— def on_cancel — для обработки события нажатия кнопки cancel в диалоговом окне с элементом MDTimePicker.
В функции def build есть две закомментированные строки, в которых находится код, обеспечивающий изменение внешнего вида диалогового окна
После запуска данного приложения получим следующий результат (рис.5.66).
Рис. 5.66. Результат выполнения приложения из модуля MDTimePicker1.py
После загрузки окна с компонентой MDTimePicker на экране появляется двенадцатичасовой циферблат, поля со временем (часы: минуты), установленным по умолчанию и две кнопки: AM — утреннее время (до 12 часов дня), PM — вечернее время (после 12 часов дня). Пользователю необходимо касанием пальца передвинуть стрелку указателя на нужные часы. После этого коснуться поля с указанием минут, в результате этого на экране появится циферблат с интервалов времени 0—59 минут. Касанием пальца выбирается требуемое количество минут (рис.5.67).
Рис. 5.67. Циферблаты для установки часов и минут в компоненте MDTimePicker
Выбор установленного времени осуществляется нажатием на кнопку OK. При этом значение выбранного времени будет зависеть от состояния переключателя AM/PM. Если переключатель будет находиться в положении AM (время до обеда), то диалоговое окно вернет значение времена в формате 10:40:00. Если переключатель будет находиться в положении PM (время после обеда), то диалоговое окно вернет значение времени в формате 22:40:00 (рис.5.68).
Рис. 5.68. Влияние переключателя AM/PM на значение выбранного времени в компоненте MDTimePicker
5.22.2. MDDatePicker — панель для задания даты
Рассмотрим реализацию панели для выбора и задания даты на простом примере. Для этого создадим файл MDDatePicker1.py и напишем в нем следующий код (листинг 5.53).
Листинг 5.53. Демонстрации работы класса MDDatePicker (модуль MDDatePicker1.py)
# модуль MDDatePicker1.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. picker import MDDatePicker
KV = «»»
MDFloatLayout:
…… MDToolbar:
…… …… title: «Компонента MDDatePicker»
…… …… pos_hint: {«top»: 1}
…… …… elevation: 10
…… MDRaisedButton:
…… …… text: «Открыть Date Picker»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.6}
…… …… on_release: app.show_date_picker ()
…… MDLabel:
…… …… id: date_label
…… …… text: «Итоги выбора даты!»
…… …… halign: «center»
«»»
class Main (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_save (self, instance, value, date_range):
…… …… self.root.ids. date_label. text = str (value)
…… …… # self.root.ids. date_label. text = str (date_range)
…… def on_cancel (self, instance, value):
…… …… self.root.ids. date_label. text = «Вы Нажали Cancel!»
…… def show_date_picker (self):
…… …… date_dialog = MDDatePicker ()
…… …… # date_dialog = MDDatePicker (year=2016, month=4, day=12)
…… …… # date_dialog = MDDatePicker (min_year=2015,
…… …… …… …… …… …… max_year=2025)
…… …… # date_dialog = MDDatePicker (mode=«range»)
…… …… date_dialog.bind (on_save=self. on_save,
…… …… …… …… …… …… on_cancel=self. on_cancel)
…… …… date_dialog. open ()
Main().run ()
В данном приложении на языке разметки в строковой переменной KV создано три элемента:
— MDToolbar — верхняя панель;
— MDRaisedButton — кнопка, при нажатии на которую выполнится обращение к функции show_date_picker, где обеспечивается создание и открытие диалогового окна с элементом MDDatePicker;
— MDLabel — метка, в которую вернется и отобразится значение даты, выбранное пользователем.
В базовом классе имеется две функции:
— def on_save — для обработки события on_save (получить выбранную дату) и передачи этого значения метке date_label;
— def on_cancel — для обработки события нажатия кнопки cancel в диалоговом окне с элементом MDDatePicker.
В данном листинге есть закомментированные строки, в которых находится код, обеспечивающий изменение настроек диалогового окна. На этих настройках остановимся чуть позже.
После запуска данного приложения получим следующий результат (рис.5.69).
Рис. 5.69. Результат выполнения приложения из модуля MDDatePicker1.py
После открытия диалогового окна MDDatePicker по умолчанию установлена текущая дата. Кнопки с символами « <», «>» позволяют пролистать месяцы текущего года, а кнопка рядом с указанием текущего года позволяет открыть (и скрыть) окно для выбора другого года. После нажатия на кнопку «OK» выбранная дата будет возвращена в приложение (рис.5.70).
Рис. 5.70. Окно для смены года и результат выбора даты в модуле MDDatePicker1.py
Теперь вернемся к настройкам окна MDDatePicker. Имеется возможность установить любую начальную дату, для этого в коде вышеприведенного листинга нужно изменить комментарии в следующих строках:
# date_dialog = MDDatePicker ()
date_dialog = MDDatePicker (year=2016, month=4, day=12)
После этого при открытии окна текущая дата будет заменена на ту, которая установлена в последней строке.
Кроме того, в MDDatePicker можно выбрать интервал дат. Для демонстрации этого изменим положение знака комментария в функциях следующим образом:
def on_save (self, instance, value, date_range):
…… # self.root.ids. date_label. text = str (value)
…… self.root.ids. date_label. text = str (date_range)
…… def show_date_picker (self):
…… # date_dialog = MDDatePicker ()
…… date_dialog = MDDatePicker (year=2016, month=4, day=12)
…… date_dialog = MDDatePicker (min_year=2015, max_year=2025)
…… date_dialog = MDDatePicker (mode=«range»)
…… date_dialog.bind (on_save=self. on_save, on_cancel=self. on_cancel)
…… date_dialog. open ()
После запуска приложения в таком варианте получим следующий результат (рис.5.71).
Рис. 5.71. Окно для смены года и результат выбора даты в модуле MDDatePicker1.py
5.22.3. MDThemePicker — панель для задания параметров стиля приложения
На основе панели MDThemePicker можно изменить стиль приложения (изменить цветовую гамму). Для демонстрации возможностей этой панели создадим файл MDThemePicker.py и напишем в нем следующий код (листинг 5.54).
Листинг 5.54. Демонстрации работы класса MDThemePicker (модуль MDThemePicker.py)
# модуль MDThemePicker1
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. picker import MDThemePicker
KV = «»»
MDFloatLayout:
…… MDToolbar:
…… …… title: «Компонента Theme Picker»
…… …… pos_hint: {«top»: 1}
…… …… elevation: 10
…… MDRaisedButton:
…… …… text: «Открыть Theme Picker»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.6}
…… …… on_release: app.show_theme_picker ()
…… MDLabel:
…… …… id: date_label
…… …… text: «Итоги смены темы!»
…… …… halign: «center»
«»»
class Main (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def show_theme_picker (self):
…… …… theme_dialog = MDThemePicker ()
…… …… theme_dialog. open ()
Main().run ()
В данной программе в базовом классе создана функция show_theme_picker, которая создает объект theme_dialog на основе класса MDThemePicker, и открывает соответствующее диалоговое окно. В текстовой переменной KV имеется контейнер MDFloatLayout, в котором помещены три элемента:
— MDToolbar — верхняя панель;
— MDRaisedButton — кнопка;
— MDLabel — метка.
При запуске приложения для него устанавливается стиль «по умолчанию». Однако пользователь с использованием класса MDThemePicker может изменить этот стиль.
После запуска приложения в таком варианте получим следующий результат (рис.5.72).
Рис. 5.72. Результат выполнения приложения из модуля MDThemePicker.py
5.23. MDProgress Bar — индикатор хода выполнения процесса
Индикаторы Progress Bar информируют пользователей о состоянии текущих процессов, таких как загрузка приложения, отправка формы или сохранение файлов. В KivyMD предоставлены для использования следующие классы индикаторов:
— MDProgressBar — традиционный (определенный) индикатор;
— Determinate — неопределенный индикатор (с исчезновением);
— Indeterminate — неопределенный индикатор (без исчезновения).
Традиционные индикаторы показывают, сколько времени осталось до завершения процесса и их следует использовать только тогда, когда заранее можно определить время (или количество шагов) до завершения процесса. В течение работы фрагмента программы, связанного с традиционным индикатором, его заполнение увеличивается от 0 до 100%.
В индикаторах типа Determinate, Indeterminate бегунок движутся по фиксированной траектории, постепенно увеличиваясь, а потом уменьшаясь в размерах по мере продвижения. Его используют в том случае, когда время завершения процесса, связанного с индикатором, заранее определить невозможно.
Для демонстрации возможностей традиционного индикатора ProgressBar создадим файл MDProgressBar1.py и напишем в нем следующий код (листинг 5.55).
Листинг 5.55. Демонстрации работы класса MDProgressBar (модуль MDProgressBar1.py)
# модуль MDProgressBar1
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… padding: «10dp»
…… MDProgressBar:
…… …… value: 50
…… MDProgressBar:
…… …… value: 50
…… …… orientation: «vertical»
…… MDProgressBar:
…… …… value: 50
…… …… color: app.theme_cls.accent_color
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В данной программе в строковой переменной KV в контейнер MDBoxLayout имеется три элемента MDProgressBar: два с горизонтальным расположением и один с вертикальным. После запуска приложения в таком варианте получим следующий результат (рис.5.73).
Рис. 5.73. Результат выполнения приложения из модуля MDProgressBar1.py
Все три элемента имеют степень заполнения 50%, два элемента имеет цвет по умолчанию, для одного горизонтального элемента задан пользовательский цвет. В данном варианте программы элементы MDProgressBar статичны. Напишем небольшую программу, в которой покажем, как MDProgressBar может получать значения от других модулей или виджетов. Создадим файл MDProgressBar2.py и напишем в нем следующий код (листинг 5.56).
Листинг 5.56. Демонстрации работы класса MDProgressBar (модуль MDProgressBar2.py)
# модуль MDProgressBar2
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… name: «progress bar»
…… MDToolbar:
…… …… title: «Компонента MDProgressBar»
…… …… pos_hint: {«top»: 1}
…… …… elevation: 10
………… MDBoxLayout:
…… ………… orientation: «vertical»
…… ………… padding: «4dp»
…… ………… MDLabel:
…… …… ………… text: «Смените положение Слайдера»
…… …… ………… halign: «center»
…… ………… MDSlider:
…… …… ………… id: progress_slider
…… …… ………… min: 0
…… …… ………… max: 100
…… …… ………… value: 40
…… …… ………… hint: False
…… ………… MDProgressBar:
…… …… ………… reversed: True
…… …… ………… value: progress_slider.value
…… ………… BoxLayout:
…… …… ………… MDProgressBar:
…… …… …… ………… orientation: «vertical»
…… …… …… ………… reversed: True
…… …… …… ………… value: progress_slider.value
…… …… ………… MDProgressBar:
…… …… …… ………… orientation: «vertical»
…… …… …… ………… value: progress_slider.value
«»»
class MainApp (MDApp):
…… def build (self):
…… … … self.root = Builder. load_string (KV)
MainApp().run ()
Здесь мы создали три элемента MDProgressBar и указали, что они получают текущее значение, от еще одного элемент KivyMD — слайдера (MDSlider). После запуска приложения в таком варианте получим следующий результат (рис.5.74).
Рис. 5.74. Результат выполнения приложения из модуля MDProgressBar2.py
Как видно из данного рисунка, компонента MDProgressBar имеет 4 варианта заполнения: слева, справа, снизу, сверху.
Для демонстрации возможностей неопределенных индикаторов ProgressBar создадим файл MDProgressBar3.py и напишем в нем следующий код (листинг 5.57).
Листинг 5.57. Демонстрации работы класса MDProgressBar (модуль MDProgressBar3.py)
# модуль MDProgressBar3
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivymd. app import MDApp
KV = «»»
Screen:
…… MDProgressBar:
…… … … id: progress
…… … … pos_hint: {«center_y»:. 6}
…… … … type: «determinate»
…… … … #type: «indeterminate»
…… … … running_duration: 2
…… … … catching_duration: 1
…… MDRaisedButton:
…… … … text: «STOP» if app.state == «start» else «START»
…… … … pos_hint: {«center_x»:. 5, «center_y»:. 45}
…… … … on_press: app.state = «stop» if app.state == «start» else «start»
«»»
class MainApp (MDApp):
…… state = StringProperty («stop»)
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_state (self, instance, value):
…… …… {
…… …… «start»: self.root.ids.progress.start,
…… …… «stop»: self.root.ids.progress.stop,
…… …… }.get (value) ()
MainApp().run ()
В данной программе в строковой переменной KV в контейнер Screen (экран) имеется два элемента MDProgressBar (индикатор) с параметрами и кнопка –MDRaisedButton. В базовом модуле создана функция def on_state, которая запускает и останавливает работу индикатора. После запуска приложения в таком варианте получим следующий результат (рис.5.75).
Рис. 5.75. Результат выполнения приложения из модуля MDProgressBar3.py
Как видно из данного рисунка, у индикатора «type: „determinate“» заполнение цветной полосы происходит по всей длине шаблона индикатора, а после заполнения он полностью исчезает с экрана. У индикатора «type: „indeterminate“» цветная полоса пробегает по шаблону индикатора, при этом сам шаблон всегда находится на экране.
5.24. MDScreen — класс для размещения виджетов
Класс MDScreen позволяет создать контейнер, в котором будут размещены другие элементы. Для демонстрации возможностей этого класса создадим файл MDScreen.py и напишем в нем следующий код (листинг 5.58).
Листинг 5.58. Демонстрации работы класса MDScreen (модуль MDScreen.py)
# модуль MDScreen.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… radius: [25, 25, 25, 25]
…… md_bg_color: app.theme_cls.primary_color
…… MDRelativeLayout:
…… … … orientation: «vertical»
…… … … MDRaisedButton:
.… … … ….. … text: «КНОПКА»
…… … … … … pos_hint: {’center_x’:.5, ’center_y’:.5}
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
В данной программе в строковой переменной KV был создан контейнер MDScreen (экран), в котором размести два элемента: контейнер — MDRelativeLayout и кнопку в центре экрана (MDRaisedButton). Для экрана MDScreen установили два свойства:
— radius: [25, 25, 25, 25] — радиус округления углов
— md_bg_color: app.theme_cls.primary_color — цвет фона экрана
После запуска приложения получим следующий результат (рис.5.76).
Рис. 5.76. Результат выполнения приложения из модуля MDScreen.py
Данный виджет чаще используется в паре с менеджером экранов, что обеспечивает быструю смену экранов в окне приложения.
5.25. Selection Controls — класс для создания элементов управления (флажки, переключатели)
Флажки и переключатели — это элементы управления выбором, которые можно использовать в диалоговых окнах для выбора решений или объявления предпочтений. В KivyMD предоставлены следующие классы элементов управления:
— MDCheckbox — флажки;
— MDSwitch — переключатели.
5.25.1. Класс MDCheckbox для создания флажков
Для демонстрации возможностей класса MDCheckbox создадим файл MDCheckbox1.py и напишем в нем следующий код (листинг 5.59).
Листинг 5.59. Демонстрации работы класса MDCheckbox (модуль MDCheckbox1.py)
# модуль MDCheckbox1.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDGridLayout:
…… …… cols:2
…… …… spacing: 2
…… …… MDLabel:
…… …… …… size_hint_x: None
…… …… …… text: «Флажок 1»
…… …… MDCheckbox:
…… …… …… size_hint_x: None
…… …… …… size: «48dp», «48dp»
…… …… …… on_active: app. on_checkbox_1 (*args)
…… …… MDLabel:
…… …… …… size_hint_x: None
…… …… …… text: «Флажок 2»
…… …… MDCheckbox:
…… …… …… size_hint_x: None
…… …… …… size: «48dp», «48dp»
…… …… …… on_active: app. on_checkbox_2 (*args)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def on_checkbox_1 (self, checkbox, value):
…… … … if value:
…… … … … … print («Флажок 1 — активный»)
…… … … else:
…… … … … … print («Флажок 1 — пассивный»)
…… def on_checkbox_2 (self, checkbox, value):
…… … … if value:
…… … … … … print («Флажок 2 — активный»)
…… … … else:
…… … … … … print («Флажок 2 — пассивный»)
MainApp().run ()
В этом программном модуле создано два элемента MDCheckbox. К сожалению, данный элемент не имеет свойства, в которое можно поместить текст (метку). Поэтому здесь дополнительно создан контейнер MDGridLayout с двумя колонками. В первой колонке находится метка MDLabel, во второй колонке сам флажок MDCheckbox. В базовом модуле создано две функции, которые обрабатывают событие изменения состояния флажка. После запуска приложения получим следующий результат (рис.5.77).
Рис. 5.77. Результат выполнения приложения из модуля MDCheckbox1.py
Из данного рисунка видно, что флажки могут изменять свои состояния независимо друг от друга. Однако их можно объединить в группу, тогда в группе в активном состоянии может быть только один элемент. Проверим это на примере, создадим файл MDCheckbox2.py и напишем в нем следующий код (листинг 5.60).
Листинг 5.60. Демонстрации работы класса MDCheckbox (модуль MDCheckbox2.py)
# модуль MDCheckbox2.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
<Check@MDCheckbox>:
…… group: ’group’
…… size_hint: None, None
…… size: dp (48), dp (48)
FloatLayout:
…… Check:
…… …… active: True
…… …… pos_hint: {’center_x’:.4, ’center_y’:.5}
…… Check:
…… …… pos_hint: {’center_x’:.6, ’center_y’:.5}
…… Check:
…… …… pos_hint: {’center_x’:.8, ’center_y’:.5}
«»»
class MainApp (MDApp):
…...def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В этом программном модуле создано три элемента MDCheckbox, которые объединены в одну группу, при этом первый элемент является активным — «active: True». После запуска приложения получим следующий результат (рис.5.78).
Рис. 5.78. Результат выполнения приложения из модуля MDCheckbox2.py
Как видно из данного рисунка, если элементы MDCheckbox объединить в группу, то активным может быть только один из этих элементов.
5.25.2. Класс MDSwitch для создания переключателей
Для демонстрации возможностей класса MDSwitch создадим файл MDSwitch.py и напишем в нем следующий код (листинг 5.61).
Листинг 5.61. Демонстрации работы класса MDSwitch (модуль MDSwitch.py)
# модуль MDSwitch.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
FloatLayout:
…… MDLabel:
…… …… text: «Переключатель 1»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.5}
…… MDSwitch:
…… …… pos_hint: {’center_x’:.8, ’center_y’:.5}
…… …… on_active: app. switch_active1 (self)
…… MDLabel:
…… …… text: «Переключатель 2»
…… …… pos_hint: {’center_x’:.5, ’center_y’:.4}
…… MDSwitch:
…… …… pos_hint: {’center_x’:.8, ’center_y’:.4}
…… …… width: dp (64)
…… …… on_active: app. switch_active2 (self)
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def switch_active1 (self, instance):
…… …… print («Переключатель 1, статус -», instance.active)
…… def switch_active2 (self, instance):
…… …… print («Переключатель 2, статус -», instance.active)
MainApp().run ()
В этом программном модуле создано два элемента MDSwitch. К сожалению, данный элемент не имеет свойства, в которое можно поместить текст (метку). Поэтому здесь дополнительно создан контейнер FloatLayout. В этом контейнере находятся две метки MDLabel, и два переключателя MDSwitch. Для первого переключателя не задана ширина (будет использоваться значение по умолчанию). Для второго переключателя установлена ширина — dp (64).
В базовом модуле создано две функции, которые обрабатывают событие изменения состояния переключателей. После запуска приложения получим следующий результат (рис.5.79).
Рис. 5.79. Результат выполнения приложения из модуля MDSwitch.py
5.26. MDSelectionList — выбор элементов из списка
В KivyMD имеется класс MDSelectionList (список выбора, отбора). По своей сути это объект, обеспечивающий выделение элементов, над которыми пользователь намеревается выполнить какие либо действия. Чтобы войти в режим выбора элементов из списка, нужно коснуться их и удерживать некоторое время. Чтобы выйти из режима выбора, нужно коснуться каждого из выбранного элемента.
Для демонстрации возможностей MDSelectionList создадим файл MDSelectionList1.py и напишем в нем следующий код (листинг 5.62).
Листинг 5.62. Демонстрации работы класса MDSelectionList (модуль MDSelectionList1.py)
# модуль MDSelectionList1.py
from kivy.animation import Animation
from kivy.lang import Builder
from kivy. utils import get_color_from_hex
from kivymd. app import MDApp
from kivymd.uix.list import TwoLineAvatarListItem
KV = «»»
# описание элемента списка
<MyItem>
…… text: «Первая строка»
…… secondary_text: «Вторая строка»
…… _no_ripple_effect: True
…… ImageLeftWidget:
…… …… source: "./Images/kivymd.jpg»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… id: toolbar
…… …… title: «Список»
…… …… left_action_items: [[«menu»]]
…… …… right_action_items: [[«magnify»], [«dots-vertical»]]
…… …… md_bg_color: 0, 0, 0, 1
…… MDBoxLayout:
…… …… padding: «24dp», «8dp», 0, «8dp»
…… …… adaptive_size: True
…… …… MDLabel:
…… …… …… text: «Список»
…… …… …… adaptive_size: True
…… …… ScrollView:
…… …… …… MDSelectionList:
…… …… …… …… id: selection_list
…… …… …… …… spacing: «12dp»
…… …… …… …… overlay_color: app. overlay_color [:-1] + [.2]
…… …… …… …… icon_bg_color: app. overlay_color
…… …… …… …… on_selected: app. on_selected (*args)
…… …… …… …… on_unselected: app. on_unselected (*args)
…… …… …… …… on_selected_mode: app.set_selection_mode (*args)
«»»
class MyItem (TwoLineAvatarListItem):
…… pass
class MainApp (MDApp):
…… overlay_color = get_color_from_hex («#6042e4»)
…… def build (self):
…… …… return Builder. load_string (KV)
…… # формирование списка из 10 строк
…… def on_start (self):
…… …… for i in range (10):
…… …… self.root.ids.selection_list.add_widget (MyItem ())
…… # изменение содержания ToolBar
…… def set_selection_mode (self, instance_selection_list, mode):
…… …… if mode:
………… …… md_bg_color = self. overlay_color
………… …… left_action_items = [[
………… …… ………… …… «close»,
………… …… ………… …… lambda x: self.root.ids.selection_list.
………… …… ………… …… unselected_all (),]]
………… …… ………… …… right_action_items = [[«trash-can»], [«dots-vertical»]]
…… …… else:
………… …… md_bg_color = (0, 0, 0, 1)
………… …… left_action_items = [[«menu»]]
………… …… right_action_items = [[«magnify»], [«dots-vertical»]]
………… …… self.root.ids.toolbar. title = «Список»
…… …… Animation (md_bg_color=md_bg_color,
…… …… …… …… d=0.2).start(self.root.ids.toolbar)
…… …… self.root.ids.toolbar. left_action_items = left_action_items
…… …… self.root.ids.toolbar. right_action_items = right_action_items
…… def on_selected (self, instance_selection_list, instance_selection_item):
…… …… self.root.ids.toolbar. title = str (
…… …… …… …… len(instance_selection_list.get_selected_list_items ()))
…… def on_unselected (self, instance_selection_list, instance_selection_item):
…… …… if instance_selection_list.get_selected_list_items ():
…… …… …… self.root.ids.toolbar. title = str (
…… … … …… …… len(instance_selection_list.get_selected_list_items ()))
MainApp().run ()
В этом программном в функции def on_start создан список из 10 строк, содержащих текст и иконку. Сами элементы списка описаны в пользовательском классе <MyItem> в строковой переменной KV. В ней же создан контейнер MDBoxLayout, в котором размещена верхняя панель MDToolbar, и в блоке скроллинга, собственно сам список из 10 элементов. В базовом модуле имеются функции, обеспечивающие присвоение элементу списка признака «выбран» (def on_selected), и снятие с элемента списка признака «выбран» (def on_unselected).
После запуска приложения получим следующий результат (рис.5.80).
Рис. 5.80. Результат выполнения приложения из модуля MDSelectionList1.py
Как видно из данного рисунка, после запуска приложения появится экран с верхней панелью и списком элементов, который можно перемещать вниз-вверх с использованием скроллинга. Если коснуться и удерживать один из элементов списка, то появится элемент ProgressBar в виде кольца, этот элемент будет выделен и изменится состояния верхней панели. На верхней панели инструментов появится новая иконка, с которой можно связать любые действия над выбранными элементами (в нашем случае это корзина), и иконка «крестик» — (выхода из режима выбора элементов). В режиме выбора элементов пользователь может выделить любой элемент списка (путем касания), или снять выделение (путем повторного касания). Для выхода из режима «Выбор» нужно коснуться иконки «х».
С использованием элемента FitImage можно сформировать список изображений и его загрузить в компоненту MDSelectionList. Для демонстрации такой возможностей создадим файл MDSelectionList2.py и напишем в нем следующий код (листинг 5.63).
Листинг 5.63. Демонстрации работы класса MDSelectionList (модуль MDSelectionList2.py)
# модуль MDSelectionList2.py
from kivy.animation import Animation
from kivy.lang import Builder
from kivy. utils import get_color_from_hex
from kivymd. app import MDApp
from kivymd.utils.fitimage import FitImage
KV = «»»
…… MDBoxLayout:
…… …… orientation: «vertical»
…… …… md_bg_color: app.theme_cls.bg_light
…… …… MDToolbar:
…… …… …… id: toolbar
…… …… …… title: «Изображения»
…… …… …… left_action_items: [[«menu»]]
…… …… …… right_action_items: [[«magnify»], [«dots-vertical»]]
…… …… …… md_bg_color: app.theme_cls.bg_light
…… …… …… specific_text_color: 0, 0, 0, 1
…… …… MDBoxLayout:
…… …… …… padding: «24dp», «4dp», 0, «4dp»
…… …… …… adaptive_size: True
…… …… …… …… MDLabel:
…… … … …… …… …… text: «Собачки»
…… … … …… …… …… adaptive_size: True
…… …… ScrollView:
…… …… …… MDSelectionList:
…… …… …… …… id: selection_list
…… …… …… …… padding: «24dp», 0, «24dp», «24dp»
…… …… …… …… cols: 3
…… …… …… …… spacing: «12dp»
…… …… …… …… overlay_color: app. overlay_color [:-1] + [.2]
…… …… …… …… icon_bg_color: app. overlay_color
…… …… …… …… progress_round_color: app.progress_round_color
…… …… …… …… on_selected: app. on_selected (*args)
…… …… …… …… on_unselected: app. on_unselected (*args)
…… …… …… …… on_selected_mode: app.set_selection_mode (*args)
«»»
class MainApp (MDApp):
…… overlay_color = get_color_from_hex («#6042e4»)
…… progress_round_color = get_color_from_hex («#ef514b»)
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_start (self):
…… …… for i in range (9):
…… …… …… self.root.ids.selection_list.add_widget (
…… …… …… …… …… …… FitImage(source="./Images/Dog.jpg»,
…… …… …… …… …… …… size_hint_y=None,
…… …… …… …… …… …… height=«140dp», ))
…… def set_selection_mode (self, instance_selection_list, mode):
…… … … if mode:
…… … … … … md_bg_color = self. overlay_color
…… … … … … left_action_items = [[
…… … … … … …… … … … … «close»,
…… … … … … …… … … … … lambda x: self.root.ids.selection_list.
…… … … … … …… … … … … unselected_all (),]]
…… … … … … …… … … … … right_action_items = [[«trash-can»],
…… … … … … …… … … … … [«dots-vertical»]]
…… … … else:
…… … … … … md_bg_color = (1, 1, 1, 1)
…… … … … … left_action_items = [[«menu»]]
…… … … … … right_action_items = [[«magnify»], [«dots-vertical»]]
…… … … … … self.root.ids.toolbar. title = «Изображения»
…… … … Animation (md_bg_color=md_bg_color,
…… … … …… … … d=0.2).start(self.root.ids.toolbar)
…… … … self.root.ids.toolbar. left_action_items = left_action_items
…… … … self.root.ids.toolbar. right_action_items = right_action_items
…… def on_selected (self, instance_selection_list,
…… …… …… …… …… …… …… …… …… instance_selection_item):
…… … … self.root.ids.toolbar. title = str (
…… … … …… … … len(instance_selection_list.get_selected_list_items ()))
…… def on_unselected (self, instance_selection_list,
…… …… …… …… …… …… …… …… …… instance_selection_item):
…… … … if instance_selection_list.get_selected_list_items ():
…… …… … … self.root.ids.toolbar. title = str (
…… … … …… … … len(instance_selection_list.get_selected_list_items ()))
MainApp().run ()
Структура этой программы аналогична той, которая приведена в предыдущем листинге. Главное отличие в том, что в функции def on_start на основе объекта FitImage создан список из 9 элементов, содержащих рисунок. После запуска приложения получим следующий результат (рис.5.81).
Рис. 5.81. Результат выполнения приложения из модуля MDSelectionList2.py
Здесь, по аналогии с предыдущей программой, для выделения элемента нужно коснуться его и удерживать некоторое время.
5.27. MDSeparator — класс для создания разделительной линии
Класс MDSeparator (разделитель) позволяет отобразить горизонтальную линию, с помощью которой можно отобразить границу между элементами интерфейса.
Для демонстрации использования этого класса, создадим файл MDSeparator.py и напишем в нем следующий код (листинг 5.64).
Листинг 5.64. Демонстрации работы класса MDSeparator (модуль MDSeparator.py)
# модуль MDSeparator.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
BoxLayout:
…… orientation: «vertical»
…… padding: dp (10)
…… spacing: dp (10)
…… MDSeparator:
…… MDRaisedButton:
…… …… text: «КНОПКА 1»
…… MDSeparator:
…… …… color: 1,0,0,1
…… MDRaisedButton:
…… …… text: «КНОПКА 2»
…… MDSeparator:
…… …… color: 0,1,0,1
…… MDRaisedButton:
…… …… text: «КНОПКА 3»
…… MDSeparator:
…… …… color: 0,0,1,1
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В этой программе создан корневой виджет — контейнер BoxLayout, в который помещено три кнопки MDRaisedButton. Кнопки отделены друг от друга разделительной линией MDSeparator, при этом для каждой линии задан свой цвет. После запуска данного приложения получим следующий результат (рис.5.82).
Рис. 5.82. Результат выполнения приложения из модуля MDSeparator.py
5.28. MDSlider — ползунок для выбора значения из заданного диапазона
Класс MDSlider (ползунок, бегунок) обеспечивает создание элемента, который позволяет пользователям просматривать и выбирать значение параметра из заданного диапазона. Ползунок находится на полосе и идеально подходит для настройки таких параметров, как громкость, яркость или фильтров для изображений.
Для демонстрации возможностей этого элемента создадим файл MDSlider1.py и напишем в нем следующий код (листинг 5.65).
Листинг 5.65. Демонстрации работы класса MDSlider (модуль MDSlider1.py)
# модуль MDSlider1.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDBoxLayout:
…… …… MDSlider:
………… …… id: slider
………… …… min: 0
………… …… max: 100
………… …… step: 1
………… …… #orientation: ’vertical’
…… …… MDLabel:
………… …… text: str(slider.value)
«»»
class MainApp (MDApp):
…… def build (self):
…… … … self.root = Builder. load_string (KV)
MainApp().run ()
В данной программе в контейнерах MDScreen и MDBoxLayout находятся две компоненты: бегунок (MDSlider) и метка (MDLabel). Для бегунка заданы следующие свойства:
— id: — идентификатор (slider);
— min: — минимальное значение (0);
— max: — максимальное значение (100);
— step: шаг изменение значения (1);
— #orientation: ориентация (по умолчанию горизонтальная, если снять комментарий с данной строки, то будет вертикальная «’vertical’»).
После запуска приложения получим следующий результат (рис.5.83).
Рис. 5.83. Результат выполнения приложения из модуля MDSlider1.py
Как видно из данного рисунка, пока бегунок не активен, то текущее значение не отображается. Как только пользователь начинает перемещение бегунка, маркер бегунка увеличивается и над ним появляется установленное им значение. После того, как бегунок будет отпущен, маркер возвращается в исходное состояние. В программе была создана метка (Label) и для ее свойства text установлено значение, заданное в бегунке. Таким образом, по мере изменение положения бегунка в данной метке также будет отображаться установленное в нем значение. Если снять комментарий со строки #orientation: ’vertical’, то бегунок сменить горизонтальное положение на вертикальное.
Познакомимся с еще несколькими свойствами и возможностями компоненты MDSlider. Для этого создадим файл MDSlider2.py и напишем в нем следующий код (листинг 5.66).
Листинг 5.66. Демонстрации работы класса MDSlider (модуль MDSlider2.py)
# модуль MDSlider2.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDScreen:
…… MDBoxLayout:
…… … … orientation: «vertical»
…… … … padding: «8dp»
…… … … MDSlider:
…… …… … … id: slider1
…… …… … … min: 0
…… …… … … max: 100
…… …… … … step: 1
…… …… … … hint: False
…… …… … … on_touch_up: app.slider_value (self)
…… … … MDLabel:
…… …… … … text: str(slider1.value)
…… … … MDSlider:
…… …… … … id: slider2
…… …… … … min: 0
…… …… … … max: 100
…… …… … … on_touch_up: app.slider_value (self)
…… … … MDLabel:
…… …… … … text: str(slider2.value)
…… … … MDSlider:
…… …… … … id: slider3
…… …… … … min: 0
…… …… … … max: 100
…… …… … … step: 1
…… …… … … color: app.theme_cls.accent_color
…… …… … … on_touch_up: app.slider_value (self)
…… … … MDLabel:
…… …… … … text: str(slider3.value)
«»»
class MainApp (MDApp):
…… def build (self):
…… …… self.root = Builder. load_string (KV)
…… def slider_value (self, instance):
…… …… if instance.active:
…… …… …… print («Значение -», instance.value)
MainApp().run ()
В данной программе в контейнерах MDScreen и MDBoxLayout находятся три бегунка MDSlider (slider1, slider2, slider3) и три связанные с ними метки (MDLabel). Для бегунка slider1 задано свойство «hint: False», поэтому при перемещении бегунка над ним не будет отображаться текущее значение. Для бегунка slider2 не задано свойство «step:», поэтому шаг изменения значения бегунка будет установлен по умолчанию (с дробной частью). Для бегунка slider3 задано свойство «color:», поэтому он будет иметь другой цвет. Наконец, для всех трех элементов MDSlider обрабатывается событие on_touch_up (бегунок отпущен). В этом случае установленное пользователем значение бегунка будет передано в функцию «def slider_value», где его можно использовать в других модулях программы.
После запуска приложения получим следующий результат (рис.5.84).
Рис. 5.84. Результат выполнения приложения из модуля MDSlider2.py
5.29. Snackbar — временная информационная панель
В KivyMD компонента (панель) Snackbar информирует пользователей о процессе в приложении, который уже выполнен или будет выполняться. Эта панель временно появляется в нижней части экрана и для ее исчезновения не требуется дополнительных действий со стороны пользователя.
Для демонстрации возможностей этого элемента создадим файл Snackbar1.py и напишем в нем следующий код (листинг 5.67).
Листинг 5.67. Демонстрации работы класса Snackbar (модуль Snackbar1.py)
# модуль Snackbar.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
#:import Snackbar kivymd.uix.snackbar.Snackbar
Screen:
…… MDRaisedButton:
…… …… text: «Открыть Snackbar»
…… …… on_release: Snackbar (text=«Это временная панель
…… …… …… …… …… …… …… Snackbar!»).open ()
…… …… pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В этой программе в строковой переменной KV был выполнен импорт компоненты Snackbar:
#:import Snackbar kivymd.uix.snackbar.Snackbar
Затем в контейнере Screen создана кнопка MDRaisedButton. При возникновении события «нажатие кнопки» (on_release) происходит открытие временно панели Snackbar:
on_release: Snackbar (text=«Это временная панель Snackbar!»).open ()
После запуска приложения получим следующий результат (рис.5.85).
Рис. 5.85. Результат выполнения приложения из модуля Snackbar1.py
В этом приложении и импорт модуля Snackbar и его вызов был реализован на уровне строковой переменной KV. Однако вызвать временную панель можно из любой функции приложения. Для демонстрации такой возможности создадим файл Snackbar2.py и напишем в нем следующий код (листинг 5.68).
Листинг 5.68. Демонстрации работы класса Snackbar (модуль Snackbar2.py)
# модуль Snackbar2.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd.uix.snackbar import Snackbar
KV = «»»
Screen:
…… MDFloatingActionButton:
…… …… x: root. width — self. width — dp (10)
…… …… y: dp (10)
…… …… on_release: app.snackbar_show ()
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def snackbar_show (self):
…… …… Snackbar (text=«Это временная панель Snackbar!»).open ()
MainApp().run ()
В этой программе и импорт модуля Snackbar и открытие временной панели выполнено за пределами строковой переменной KV. После запуска данного приложения получим следующий результат (рис.5.86).
Рис. 5.86. Результат выполнения приложения из модуля Snackbar2.py
5.30. MDSpinner — круговой индикатор процесса
Класс MDSpinner позволяет создать круговой индикатор, который будет отображаться на экране, показывая выполнение продолжительного процесса. Для демонстрации возможностей этого элемента создадим файл MDSpinner.py и напишем в нем следующий код (листинг 5.69).
Листинг 5.69. Демонстрации работы класса MDSpinner (модуль MDSpinner.py)
# модуль MDSpinner.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
Screen:
…… MDSpinner:
…… …… size_hint: None, None
…… …… size: dp (46), dp (46)
…… …… pos_hint: {’center_x’:.5, ’center_y’:.8}
…… …… #determinate: True
…… …… active: True if check.active else False
…… MDCheckbox:
…… …… id: check
…… …… size_hint: None, None
…… …… size: dp (48), dp (48)
…… …… pos_hint: {’center_x’:.5, ’center_y’:.4}
…… …… active: True
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В данной программе в контейнере Screen находится два элемента: MDSpinner — круговой индикатор процесса, и MDCheckbox — флажок, имеющий идентификатор «id: check». У элемента MDSpinner есть свойство «active:», которое может принимать два значения: True — индикатор включен, и False — индикатор выключен. При этом если у элемента check флажок установлен, то круговой индикатор будет запущен, в противном случае остановлен. В программном коде есть одна закомментированная строка:
#determinate: True
Это свойство, которое обеспечивает автоматическое закрытие индикатора. Если этому свойству установить значение — True, то он закроется автоматически. После запуска данного приложения получим следующий результат (рис.5.87).
Рис. 5.87. Результат выполнения приложения из модуля MDSpinner.py
5.31. MDTabs — компонента для размещения элементов во вкладках
Вкладки (Tabs) — это компонента, которая позволяет разбить элементы интерфейса на группы и организовать быстрое переключение между этими группами. Каждая вкладка содержит контент, который отличается от контента в других вкладках. Например, на вкладках могут быть представлены разные разделы новостей, разные музыкальные жанры или разные темы документов. По сути, каждая вкладка это самостоятельный экран, и компонента Tabs позволяет быстро переключаться между этими экранами (окнами). Каждая вкладка имеет свой заголовок.
В KivyMD чтобы сформировать набор вкладок, нужно создать новый класс, унаследованный от класса MDTabsBase, и контейнер Kivy, в котором будут вложены компоненты каждой вкладки.
Когда компонента Tabs создается в Python модуле, то описание класса будет иметь следующую структуру:
class Tab (MDFloatLayout, MDTabsBase):
…… …… ««„Класс, реализующий содержимое для вкладки tab’“»
…… …… content_text = StringProperty (»»)
Когда компонента Tabs создается в модуле на языке KV, то описание класса будет иметь следующий вид:
<Tab>
…… content_text
…… MDLabel:
…… …… text: root.content_text
…… …… pos_hint: {«center_x»:. 5, «center_y»:. 5}
При этом все вкладки должны находиться внутри MDTabs виджета:
Root:
…… MDTabs:
…… …… Tab:
…… …… …… title: «Tab 1»
…… …… …… content_text: f"Это пример текста для {self. title}»
…… …… Tab:
…… …… …… title: «Tab 2»
…… …… …… content_text: f"Это пример текста для {self. title}»
…
Каждая вкладка имеет заколок, которым может быть:
— иконка;
— текстовая метка;
— иконка + текстовая метка.
Рассмотрим все эти три варианта на примерах.
Для демонстрации возможностей этого элемента с заголовками вкладок в виде иконок создадим файл MDTabs1.py и напишем в нем следующий код (листинг 5.70).
Листинг 5.70. Демонстрации работы класса MDTabs (модуль MDTabs1.py)
# модуль MDTabs1.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. tab import MDTabsBase
from kivymd. uix. floatlayout import MDFloatLayout
from kivymd. icon_definitions import md_icons
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… title: «Пример Tabs»
…… MDTabs:
…… …… id: tabs
…… …… on_tab_switch: app. on_tab_switch (*args)
<Tab>
…… MDIconButton:
…… …… id: icon
…… …… icon: root. icon
…… …… user_font_size: «48sp»
…… …… pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class Tab (MDFloatLayout, MDTabsBase):
…… ««„Класс, реализующий содержимое для tab’“»
…… pass
class MainApp (MDApp):
…… # формирование списка из 15 иконок
…… icons = list(md_icons.keys ()) [15:30]
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_start (self):
…… …… # формирование заголовков вкладок из иконок
…… …… for tab_name in self. icons:
…… …… …… self.root.ids.tabs.add_widget (Tab (icon=tab_name))
…… def on_tab_switch (self, instance_tabs, instance_tab,
…… …… …… …… …… …… instance_tab_label, tab_text):
…… …… «»»
…… …… Вызывается при переключении вкладок.
…… ……:type instance_tabs: <kivymd.uix.tab.MDTabs object>;
…… ……:param instance_tab: <__main__.Tab object>;
…… ……:param instance_tab_label:
…… …… …… …… …… <kivymd.uix.tab.MDTabsLabel object>;
…… ……:param tab_text: text or name icon of tab;
…… …… «»»
…… …… # получение иконки вкладки
…… …… count_icon = instance_tab. icon
…… …… # печать сведений о текущей вкладке
…… …… print (f"Загружена вкладка- {count_icon}» tab’»)
MainApp().run ()
В данной программе в сегменте Python создан класс Tab на основе базовых классов MDFloatLayout, MDTabsBase. В строковой переменной KV в контейнер MDBoxLayout вложены элементы:
— MDToolbar — верхняя панель;
— MDTabs — вкладки.
Для вкладок определено свойство on_tab_switch (обработка события переключения вкладок). То есть в случае переключения вкладок будет выполнено обращение к функции app. on_tab_switch, которая находится в базовом классе приложения. В этой функции в качестве примера запрограммировано всего одно действие — вывод иконки, связанной с заголовком вкладки. Также в строковой переменной KV описан класс <Tab>, который основан на кнопке с иконкой «MDIconButton».
В базовом классе MainApp формируется список из 15 иконок, которые берутся из коллекции иконок KivyMD (md_icons.keys ()). В функции def on_start формируются 15 вкладок Tab.
После запуска данного приложения получим следующий результат (рис.5.88).
Рис. 5.88. Результат выполнения приложения из модуля MDTabs1.py
Содержимое вкладок можно менять следующими способами:
— Выполнить скроллинг иконок (в горизонтальной плоскости) в верхней панели и коснуться иконки.
— Выполнить скроллинг самих вкладок (в горизонтальной плоскости), при этом происходит автоматический скроллинг самих иконок в верхней панели.
Для демонстрации возможностей этого элемента с заголовками вкладок в виде текста создадим файл MDTabs2.py и напишем в нем следующий код (листинг 5.71).
Листинг 5.71. Демонстрации работы класса MDTabs (модуль MDTabs2.py)
# модуль MDTabs2.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. floatlayout import MDFloatLayout
from kivymd. uix. tab import MDTabsBase
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… … … title: «Пример Tabs»
…… MDTabs:
…… …… id: tabs
…… …… on_tab_switch: app. on_tab_switch (*args)
<Tab>
…… MDLabel:
…… … … id: label
…… … … text: «Вкладка 0»
…… … … halign: «center»
«»»
class Tab (MDFloatLayout, MDTabsBase):
…… ««„Класс, реализующий содержимое для tab’“»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def on_start (self):
…… … … for i in range (15):
…… … … … … self.root.ids.tabs.add_widget (Tab (title=f"Вкладка {i}»))
…… def on_tab_switch (
…… … … self, instance_tabs, instance_tab, instance_tab_label, tab_text):
…… … … «««Вызывается при переключении вкладок.
…… … …:type instance_tabs: <kivymd.uix.tab.MDTabs object>;
…… … …:param instance_tab: <__main__.Tab object>;
…… … …:param instance_tab_label: <kivymd. uix. tab.
…… …… …… …… …… …… …… …… …… MDTabsLabel object>;
…… … …:param tab_text: text or name icon of tab;
…… … … «»»
…… … … instance_tab.ids.label. text = tab_text
MainApp().run ()
Структура этой программы аналогична той, которая приведена в предыдущем листинге, но при этом в самом коде есть некоторые отличия. Так в строковой переменной KV класс <Tab>, основан не на кнопке с иконкой, а на текстовой метке «MDLabel». В функции def on_tab_switch в качестве примера запрограммировано действие — вывод заголовка вкладки. В функции def on_start сформировано 15 вкладок с заголовком в виде текста.
После запуска данного приложения получим следующий результат (рис.5.89).
Рис. 5.89. Результат выполнения приложения из модуля MDTabs2.py
Для демонстрации возможностей этого элемента с заголовками вкладок в виде иконки и текста создадим файл MDTabs3.py и напишем в нем следующий код (листинг 5.72).
Листинг 5.72. Демонстрации работы класса MDTabs t (модуль MDTabs3.py)
# модуль MDTabs3.py
from kivy.lang import Builder
from kivy. uix. floatlayout import FloatLayout
from kivymd. app import MDApp
from kivymd.uix.snackbar import Snackbar
from kivymd. uix. tab import MDTabsBase
KV = «»»
BoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… left_action_items: [[«menu», lambda x: x]]
…… …… title: «Модели платьев»
…… MDTabs:
…… …… id: tabs
…… …… on_tab_switch: app. on_tab_switch (*args)
…… …… Tab:
…… …… …… icon: ’account-check’
…… …… …… title: «Флора»
…… …… …… FitImage:
…… …… …… …… source: './Images/Flora.jpg’
…… …… Tab:
…… …… …… icon: ’account-check’
…… …… …… title: «Елена»
…… …… …… FitImage:
…… …… …… …… source: './Images/Elena.jpg’
…… …… Tab:
…… …… …… icon: ’account-check’
…… …… …… title: «Фортуна»
…… …… …… FitImage:
…… …… …… …… source: './Images/Fortuna.jpg’
«»»
class Tab (FloatLayout, MDTabsBase):
…… pass
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def on_tab_switch (self, instance_tabs, instance_tab,
…… …… instance_tab_label, title):
…… …… Snackbar (text=«Вкладка-" + title).open ()
MainApp().run ()
В этой программе в строковой переменной создан контейнер BoxLayout, в котором лежат два элемента: MDToolbar — верхняя панель и MDTabs — вкладки. В MDTabs создано три вкладки, для которых определены следующие свойства:
— icon: — имя иконки (’account-check’);
— title: — заголовок вкладки (например, «Фортуна»);
— FitImage: — контейнер для размещения рисунка (для него указана папка с рисунком).
Сам класс Tab создан в блоке программы на языке Python на основе базовых классов FloatLayout, MDTabsBase:
class Tab (FloatLayout, MDTabsBase):
В базовом классе создана функция def on_tab_switch, в которой обрабатывается событие смены вкладок. Для данного примера здесь в нижней части экрана будет появляться элемент Snackbar с именем текущей вкладки.
После запуска данного приложения получим следующий результат (рис.5.90).
Рис. 5.90.
Результат выполнения приложения из модуля MDTabs3.py
Как видно из данного рисунка, в заголовке вкладок присутствует и иконка, и надпись. После смены вкладки в нижней части окна появляется временная панель, на которой отображается заголовок текущей вкладки. Этот элемент не является обязательным, в данной программе он используется для демонстрации возможности обработки события «смена вкладки».
5.32. MDTapTargetView — компонента для формирования подсказок
Данная компонента используется для выдачи подсказок в окне полукруглой формы. Для демонстрации возможностей этого элемента создадим файл TapTargetView.py и напишем в нем следующий код (листинг 5.73).
Листинг 5.73. Демонстрации работы класса TapTargetView (модуль TapTargetView.py)
# модуль TapTargetView.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. taptargetview import MDTapTargetView
KV = «»»
Screen:
…… MDFloatingActionButton:
…… … … id: button
…… … … icon: «plus»
…… … … pos: 10, 10
…… … … on_release: app. tap_target_start ()
«»»
class MainApp (MDApp):
…… def build (self):
…… … … screen = Builder. load_string (KV)
…… … … self. tap_target_view = MDTapTargetView (
…… … … …… … … …… … … widget=screen.ids. button,
…… … … …… … … …… … … title_text=«Открывающаяся панель»,
…… … … …… … … …… … … description_text=«Здесь можно разместить текст»,
…… … … …… … … …… … … widget_position=«left_bottom», )
…… … … return screen
…… def tap_target_start (self):
…… …… if self.tap_target_view.state == «close»:
…… …… …… self.tap_target_view.start ()
…… …… else:
…… …… …… self.tap_target_view.stop ()
MainApp().run ()
После запуска данного приложения получим следующий результат (рис. 5.91).
Рис. 5.91.
Результат выполнения приложения из модуля MDTabs3.py
Примечание.
На момент написания данной книги при закрытии этого элемента возникала ошибка. Разработчики библиотеки обещали исправить этот баг, так что к моменту выхода книги в свет ошибка, скорее всего, будет найдена и исправлена.
5.33. Text Field — компонента для ввода текста
Компонента Text Field (текстовое поле) обеспечивает пользователям ввод и редактирование текста. В KivyMD реализованы следующие классы текстовых полей:
— MDTextField — текстовое поле без рамок;
— MDTextFieldRect — текстовое поле в рамке;
— MDTextFieldRound — текстовое поле в рамке с округлыми углами.
5.33.1. MDTextField — текстовое поле без рамок
Класс MDTextField позволяет создать поле без рамок для ввода текста. Такое поле с параметрами по умолчанию выделено в окне приложения нижней линией подчеркивания.
Примечание.
Текстовое поле MDTextField унаследовано от класса TextInput фреймворка Kivy. Следовательно, большинство параметров и все события класса TextInput также доступны и в классе MDTextField.
Для демонстрации возможностей класса MDTextField создадим файл MDTextField.py и напишем в нем следующий код (листинг 5.74).
Листинг 5.74. Демонстрации работы класса MDTextField (модуль MDTextField.py)
# модуль MDTextField1.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
BoxLayout:
…… orientation: «vertical»
…… MDTextField:
…… …… hint_text: «Введите текст»
…… MDTextField:
…… …… hint_text: «Дата рождения»
…… …… helper_text: «дд/мм/гггг»
…… …… helper_text_mode: «on_focus»
…… MDTextField:
…… …… hint_text: «Введите ФИО»
…… …… helper_text: «Фамилия Имя Отчество»
…… …… helper_text_mode: «persistent»
…… MDTextField:
…… …… hint_text: «Max. символов- 5»
…… …… max_text_length: 5
…… MDTextField:
…… …… hint_text: «Прямоугольный режим»
…… …… mode: «rectangle»
…… MDTextField:
…… …… multiline: True
…… …… hint_text: «Это многострочный текст»
…… MDTextField:
…… …… hint_text: «Режим заполнения»
…… …… mode: «fill»
…… …… fill_color: 0, 0, 0,.1
…… MDTextField:
…… …… hint_text: «Задать цвет линии»
…… …… line_color_normal: app.theme_cls.accent_color
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В данной программе создано несколько текстовых полей, каждое из которых имеет набор свойств. Компонента MDTextField может иметь следующий набор свойств:
— hint_text: — текст подсказки, который находится в текстовом поле до ввода в него информации (например, «Введите текст»);
— helper_text: — вспомогательный текст, который появляется под текстовым полем в момент ввода информации (например, формат ввода даты «дд/мм/гггг»);
— helper_text_mode: — режим показа вспомогательного текста, может принимать значения:
— «on_focus» — в фокусе (текст подсказки появляется тогда, когда пользователь начал вводить информацию в текстовое поле);
— «persistent» — постоянный (текст подсказки постоянно находится под текстовым полем);
— «on_error» — позволяет отобразить ошибку пользователя при вводе информации в текстовое поле.
— «rectangle» — прямоугольный режим (наличие ограничивающей рамки вокруг текстового поля;
— «fill» — заполнить (залить) текстовое поле цветным фоном.
— max_text_length: — максимально допустимое количество символов в текстовом поле (например, 5);
— «Multi-line text»: — многострочное текстовое поле (может содержать несколько строк);
— color_mode: — цвет линии, выделяющей текстовое поле (например, ’accent’);
— line_color_focus: — цвет линии, выделяющей текстовое поле в момент ввода информации (например — 1, 0, 1, 1);
— fill_color: — цвет, которым будет залито текстовое поле (например — 0, 0, 0,.1);
— max_height: -максимальная высота, которую может занимать текстовое поле (обычно используется для многострочных текстовых полей, например, «200dp»).
После запуска данного приложения получим следующий результат (рис.5.92).
Рис. 5.92. Результат выполнения приложения из модуля MDTextField.py
5.33.2. MDTextFieldRect — текстовое поле в прямоугольной рамке
В отличие от предыдущего текстового поле класс MDTextFieldRect позволяет создавать текстовые поля с ограничивающим прямоугольником.
Примечание.
Текстовое поле MDTextFieldRect унаследовано от класса TextInput фреймворка Kivy. Следовательно, большинство параметров и все события класса TextInput также доступны и в классе MDTextField.
Для демонстрации возможностей класса MDTextFieldRect создадим файл MDTextFieldRect.py и напишем в нем следующий код (листинг 5.75).
Листинг 5.75. Демонстрации работы класса MDTextFieldRect (модуль MDTextFieldRect.py)
# модуль MDTextFieldRect.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
BoxLayout:
…… orientation: «vertical»
…… MDTextFieldRect:
…… … … size_hint: 1, None
…… … … hint_text: «Высота рамки 30»
…… … … height: «30dp»
…… MDTextFieldRect:
…… … … size_hint: 1, None
…… … … hint_text: «Высота рамки 60»
…… … … height: «60dp»
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
Для данного поля можно указать высоту рамки с использованием свойства height. После запуска данного приложения получим следующий результат (рис.5.93).
Рис. 5.93. Результат выполнения приложения из модуля MDTextFieldRect.py
5.33.3. MDTextFieldRound — текстовое поле в рамке с округлыми углами
Класс MDTextFieldRound позволяет создать поле для ввода текста в прямоугольнике с округлыми углами. В этой рамке можно размещать иконки слева и справа от текста. Компонента MDTextFieldRound может иметь следующий набор свойств:
— width: — ширина поля (например, 300);
— icon_left: — наличие иконки в левом углу поля (например, «email»);
— icon_right: — наличие иконки в правом углу поля (например, ’eye-off’);
— normal_color: — задание цвета поля в нормальном (пассивном) состоянии (например, app.theme_cls.accent_color);
— color_active: — задание цвета поля в активном состоянии (например -0, 1, 0, 1).
Для демонстрации возможностей класса MDTextFieldRound создадим файл MDTextFieldRound.py и напишем в нем следующий код (листинг 5.76).
Листинг 5.76. Демонстрации работы класса MDTextFieldRound (модуль MDTextFieldRound.py)
# модуль MDTextFieldRound.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
…… BoxLayout:
…… … … orientation: «vertical»
…… … … MDTextFieldRound :
…… …… … … hint_text: «Введите текст»
…… …… … … width: 300
…… …… … … size_hint_x: None
…… …… … … pos_hint: {«center_x»:. 5}
…… … … MDTextFieldRound :
…… …… … … hint_text: «Поле с одной иконкой»
…… …… … … icon_left: «email»
…… …… … … width: 300
…… …… … … size_hint_x: None
…… …… … … pos_hint: {«center_x»:. 5}
…… … … MDTextFieldRound :
…… …… … … hint_text: «Поле с двумя иконками»
…… …… … … icon_left: ’key-variant’
…… …… … … icon_right: ’eye-off’
…… …… … … width: 300
…… …… … … size_hint_x: None
…… …… … … pos_hint: {«center_x»:. 5}
…… … … MDTextFieldRound :
…… …… … … hint_text: «Поле с указанием цвета»
…… …… … … icon_left: ’key-variant’
…… …… … … normal_color: app.theme_cls.accent_color
…… …… … … width: 300
…… …… … … size_hint_x: None
…… …… … … pos_hint: {«center_x»:. 5}
…… … … MDTextFieldRound :
…… …… … … hint_text: «Изменение активного цвета»
…… …… … … icon_left: ’key-variant’
…… …… … … color_active: 0, 1, 0, 1
…… …… … … width: 300
…… …… … … size_hint_x: None
…… …… … … pos_hint: {«center_x»:. 5}
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.94).
Рис. 5.94. Результат выполнения приложения из модуля MDTextFieldRound.py
5.34. Toolbar — компонента панель инструментов
В библиотеке KivyMD имеется два класса для создания панелей инструментов:
— MDToolbar — панель инструментов в верхней части окна приложения;
— MDBottomAppBar — панель инструментов в нижней части окна приложения.
Для класса MDToolbar с использованием свойства «type:» можно задать позицию расположения панели инструментов:
— расположить в верхней части окна приложения — type: «top» (задано по умолчанию);
— расположить в нижней части окна приложения — type: «bottom».
Верхняя и нижняя панель инструментов предоставляют контент и действия, связанные с текущим экраном. Верхняя панель в основном используется для брэндинга приложения, размещения заголовков экранов, иконок для навигации по приложению и запуска в действие запрограммированных функций. Аналогичные компоненты могут быть размещены и в нижней панели инструментов.
Для того, чтобы поместить панель инструментов в нижней части экрана, нужно задействовать два класса: MDBottomAppBar и MDToolbar. Рассмотрим примеры размещения панели инструментов верхней и нижней части экрана.
5.34.1. MDToolbar — верхняя панель инструментов
Для создания верхней панели инструментов используется базовый класс MDToolbar. Для демонстрации возможностей класса MDToolbar создадим файл MDToolbar1.py и напишем в нем следующий код (листинг 5.77).
Листинг 5.77. Демонстрации работы класса MDToolbar (модуль MDToolbar1.py)
# модуль MDToolbar1.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… title: «Панель MDToolbar»
…… MDLabel:
…… …… text: «Содержимое экрана»
…… …… halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
В данном приложении в строковой переменной KV создан контейнер MDBoxLayout, в котором разместили два элемента:
— MDToolbar — верхняя панель инструментов (для панели задан заголовок);
— MDLabel — текстовая метка (контент основного экрана приложения).
После запуска данного приложения получим следующий результат (рис.5.95).
Рис. 5.95. Результат выполнения приложения из модуля MDToolbar1.py
Как видно из данного рисунка, по умолчанию панель инструментов заняло верхнюю часть экрана, и для нее задан всего один параметр — заголовок.
Обычно на панели инструментов размещают кнопку, которая позволяет открыть меню приложения. Эта кнопка может находиться как слева, так и справа от заголовка. Для демонстрации создания кнопки меню создадим файл MDToolbar2.py и напишем в нем следующий код (листинг 5.78).
Листинг 5.78. Демонстрации работы класса MDToolbar (модуль MDToolbar2.py)
# модуль MDToolbar2.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… title: «Панель MDToolbar»
…… …… left_action_items: [[«menu», lambda x: app.callback ()]]
…… MDLabel:
…… …… text: «Содержимое экрана»
…… …… halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback (self):
…… …… print («Нажата кнопка меню»)
MainApp().run ()
В этом приложении для свойства «left_action_items» задана иконка, и лямбда функция «app.callback ()», которая будет вызвана при касании иконки. После запуска данного приложения получим следующий результат (рис.5.96).
Рис. 5.96. Результат выполнения приложения из модуля MDToolbar2.py
На панели инструментов можно разместить две кнопки, которые позволяет обратиться к разным меню приложения. Обычно слева размещают кнопку с иконкой в виде трех полосок, а справа иконку в виде трех точек. Для демонстрации создания двух кнопок меню создадим файл MDToolbar3.py и напишем в нем следующий код (листинг 5.79).
Листинг 5.79. Демонстрации работы класса MDToolbar (модуль MDToolbar3.py)
# модуль MDToolbar3.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… title: «Панель MDToolbar»
…… …… left_action_items: [[«menu», lambda x: app.callback_l ()]]
…… …… right_action_items: [[«dots-vertical», lambda x: app.callback_r ()]]
…… MDLabel:
…… …… text: «Содержимое экрана»
…… …… halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback_l (self):
…… …… print («Нажата левая кнопка меню»)
…… def callback_r (self):
…… …… print («Нажата правая кнопка меню»)
MainApp().run ()
В этом приложении заданы два свойства:
— left_action_items — левая иконка («menu»), и связанная с ней лямбда функция «app.callback_l ()»;
— right_action_items — правая иконка («dots-vertical»), и связанная с ней лямбда функция «app.callback_r ()».
После запуска данного приложения получим следующий результат (рис.5.97).
Рис. 5.97. Результат выполнения приложения из модуля MDToolbar3.py
Кроме иконок, связанных с меню, на панели инструментов можно поместить и иконки для выполнения других действий. Для демонстрации создания трех кнопок с иконками создадим файл MDToolbar4.py и напишем в нем следующий код (листинг 5.80).
Листинг 5.80. Демонстрации работы класса MDToolbar (модуль MDToolbar4.py)
# модуль MDToolbar3.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… … … title: «Панель MDToolbar»
…… … … left_action_items: [[«menu», lambda x: app.callback_l ()]]
…… … … right_action_items: [[«dots-vertical»,
…… …… …… …… …… …… …… lambda x: app.callback_r ()],
……… … … … … … … … … … … [«clock», lambda x: app.callback_3 ()]]
…… MDLabel:
…… … … text: «Содержимое экрана»
…… … … halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def callback_l (self):
.… ….. … print («Нажата левая кнопка меню»)
…… def callback_r (self):
…… … … print («Нажата правая кнопка меню»)
…… def callback_3 (self):
…… … … print («Нажата кнопка — часы»)
MainApp().run ()
В этом приложении свойства right_action_items заданы две иконки, и две связанные с ними функции. Соответственно в базовом классе приложения созданы три функции для обработки событий касания кнопок (callback_l, callback_r, callback_3). После запуска данного приложения получим следующий результат (рис.5.98).
Рис. 5.98. Результат выполнения приложения из модуля MDToolbar4.py
Разработчик может изменить настройки внешнего вида панели, которые установлены по умолчанию. Для этого используются следующие свойства:
— md_bg_color: — изменить цвет фона (например, app.theme_cls.accent_color);
— specific_text_color: — изменить цвет текста (например — 0,0,1,1);
— elevation: — создать тень под панелью инструментов (например — 20).
Для демонстрации использования этих свойств создадим файл MDToolbar5.py и напишем в нем следующий код (листинг 5.81).
Листинг 5.81. Демонстрации работы класса MDToolbar (модуль MDToolbar5.py)
# модуль MDToolbar5.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDToolbar:
…… …… title: «Панель MDToolbar»
…… …… md_bg_color: app.theme_cls.accent_color
…… …… specific_text_color: 0,0,1,1
…… …… elevation: 20
…… …… left_action_items: [[«menu», lambda x: app.callback_l ()]]
…… …… right_action_items: [[«dots-vertical»,
………… …… …… …… …… …… lambda x: app.callback_r ()]]
…… MDLabel:
…… …… text: «Содержимое экрана»
…… …… halign: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback_l (self):
…… …… print («Нажата левая кнопка меню»)
…… def callback_r (self):
…… …… print («Нажата правая кнопка меню»)
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.99).
Рис. 5.99. Результат выполнения приложения из модуля MDToolbar5.py
5.34.2. MDBottomAppBar — нижняя панель инструментов
Для создания нижней панели инструментов используется тот же базовый класс MDToolbar. При этом ему нужно задать следующее значение свойства «type: „bottom“», и расположить этот элемент в другом контейнере — MDBottomAppBar. Для демонстрации возможностей класса MDToolbar с нижним расположением создадим файл MDToolbar6.py и напишем в нем следующий код (листинг 5.82).
Листинг 5.82. Демонстрации работы класса MDToolbar (модуль MDToolbar6.py)
# модуль MDToolbar6.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
…… MDBoxLayout:
.… ….. … orientation: «vertical»
…… MDLabel:
…… … … text: «Содержимое экрана»
…… … … halign: «center»
…… MDBottomAppBar:
…… … … MDToolbar:
…… …… … … title: «Панель»
…… …… … … icon: «git»
…… …… … … type: «bottom»
…… …… … … left_action_items: [[«menu», lambda x: app.callback_m ()]]
…… …… … … on_action_button: app.callback_i ()
«»»
class MainApp (MDApp):
…… def build (self):
…… … … return Builder. load_string (KV)
…… def callback_m (self):
…… … … print («Нажата левая кнопка меню»)
…… def callback_i (self):
…… … … print («Нажата иконка»)
MainApp().run ()
В этом приложении в контейнере MDBoxLayout в качестве контента основного экрана помещена метка MDLabel. А в нижней части экрана в контейнере MDBottomAppBar находится панель инструментов MDToolbar. На этой панели имеется две иконки:
— left_action_items — левая иконка на панели («menu»);
— icon: — иконка в центре панели («git»).
Для обработки событий касания иконок имеется две функции:
— callback_m — обработка события касания левой иконки панели
— callback_i — обработка события касания плавающей иконки панели.
После запуска данного приложения получим следующий результат (рис.5.100).
Рис. 5.100. Результат выполнения приложения из модуля MDToolbar6.py
По умолчанию плавающая иконка располагается в центре нижней панели, частично перекрывая ее. Однако у этой иконки есть свойство mode (режим), указывающее способ размещения. Это свойство может принимать следующие значения:
— ’free-end’ — над панелью (в конце панели справа);
— ’free-center’ — над панелью (в центре);
— ’end’ — в конце панели (справа, частично перекрывая панель);
— ’center’ — в центре панели (частично перекрывая панель).
Для демонстрации возможностей класса MDToolbar с разным расположением плавающей иконки создадим файл MDToolbar7.py и напишем в нем следующий код (листинг 5.83).
Листинг 5.83. Демонстрации работы класса MDToolbar (модуль MDToolbar7.py)
# модуль MDToolbar7.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDLabel:
…… …… text: «Содержимое экрана»
…… …… halign: «center»
…… MDBottomAppBar:
…… …… MDToolbar:
…… …… …… title: «Панель»
…… …… …… icon: «git»
…… …… …… type: «bottom»
…… …… …… left_action_items: [[«menu», lambda x: app.callback_m ()]]
…… …… …… on_action_button: app.callback_i ()
…… …… …… #mode: «free-end»
…… …… …… #mode: «free-center»
…… …… …… #mode: «end»
…… …… …… #mode: «center»
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback_m (self):
…… …… print («Нажата левая кнопка меню»)
…… def callback_i (self):
…… …… print («Нажата иконка»)
MainApp().run ()
В данной программе свойство #mode закомментировано. Поочередно снимая комментарии с этих строк, получим следующие результаты при запуске программы (рис.5.101).
Рис. 5.101. Результат выполнения приложения из модуля MDToolbar7.py
Разработчик может изменить настройки внешнего вида нижней панели, которые установлены по умолчанию. Для этого используются следующие свойства панели:
— icon_color: — изменить цвет иконки (например 1, 0, 0, 1);
— specific_text_color: — изменить цвет текста (например — 0, 0, 1, 1).
У нижней панели инструментов нет свойства для задания цвета. Однако цвет фона можно задать с помощью соответствующего свойства контейнера MDBottomAppBar.
Для демонстрации использования этих свойств нижней панели инструментов создадим файл MDToolbar8.py и напишем в нем следующий код (листинг 5.84).
Листинг 5.84. Демонстрации работы класса MDToolbar (модуль MDToolbar8.py)
# модуль MDToolbar8
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
MDBoxLayout:
…… orientation: «vertical»
…… MDLabel:
…… …… text: «Содержимое экрана»
…… …… halign: «center»
…… MDBottomAppBar:
…… …… md_bg_color: 0, 1, 0, 1
…… …… …… MDToolbar:
…… …… …… …… title: «Панель»
…… …… …… …… icon: «git»
…… …… …… …… type: «bottom»
…… …… …… …… icon_color: 1, 0, 0, 1
…… …… …… …… specific_text_color: 0,0,1,1
…… …… …… …… left_action_items: [[«menu», lambda x:
…… …… …… …… …… …… …… …… …… app.callback_m ()]]
…… …… …… …… on_action_button: app.callback_i ()
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
…… def callback_m (self):
…… …… print («Нажата левая кнопка меню»)
…… def callback_i (self):
…… …… print («Нажата иконка»)
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.102).
Рис. 5.102. Результат выполнения приложения из модуля MDToolbar8.py
5.35. Tooltip — всплывающая подсказка
Во всплывающих подсказках отображается информативный текст, когда пользователи наводят курсор на элемент или касаются его.
Примечание.
Поведение всплывающих подсказок на настольных компьютерах и мобильных устройствах различается.
Чтобы использовать MDTooltip, необходимо создать новый пользовательский класс, унаследованный от класса MDTooltip и класса соответствующего виджета. Например, если нужно связать всплывающую подсказку с иконкой, то в коде на Python описание нового пользовательского класса будет выглядеть следующим образом:
class TooltipMDIconButton (MDIconButton, MDTooltip):
…… pass
В коде на языке KV это делается в строковой переменно KV:
KV = «»»
<TooltipMDIconButton@MDIconButton+MDTooltip>
Для демонстрации использования всплывающих подсказок на основе класса, созданного на языке KV, создадим файл MDTooltip1.py и напишем в нем следующий код (листинг 5.85).
Листинг 5.85. Демонстрации работы класса MDTooltip (модуль MDTooltip1.py)
# модуль MDTooltip.py
from kivy.lang import Builder
from kivymd. app import MDApp
KV = «»»
<TooltipMDIconButton@MDIconButton+MDTooltip>
Screen:
TooltipMDIconButton:
…… icon: «language-python»
…… tooltip_text: «Язык программирования Python»
…… pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
После запуска данного приложения получим следующий результат (рис.5.103).
Рис. 5.103. Результат выполнения приложения из модуля MDTooltip1.py
Как видно из данного рисунка, если коснуться и удерживать иконку, то появиться всплывающая подсказка.
Для демонстрации использования всплывающих подсказок на основе класса, созданного в разделе кода на языке Python, создадим файл MDTooltip2.py и напишем в нем следующий код (листинг 5.86).
Листинг 5.86. Демонстрации работы класса MDTooltip (модуль MDTooltip2.py)
# модуль MDTooltip2.py
from kivy.lang import Builder
from kivymd. app import MDApp
from kivymd. uix. button import MDIconButton
from kivymd.uix.tooltip import MDTooltip
KV = «»»
Screen:
…… TooltipMDIconButton:
…… …… icon: «language-python»
…… …… tooltip_text: «Язык программирования Python»
…… …… pos_hint: {«center_x»:. 5, «center_y»:. 5}
«»»
class TooltipMDIconButton (MDIconButton, MDTooltip):
…… pass
class MainApp (MDApp):
…… def build (self):
…… …… return Builder. load_string (KV)
MainApp().run ()
После запуска данного приложения получим тот же результат, что и на предыдущем рисунке.
Краткие итоги
В данной главе мы познакомились с классами библиотеки KivyMD. Они позволяют создавать элементы интерфейса, с которыми взаимодействуют пользователи. Абсолютно для каждого класса приведены примеры программного кода. Это с одной стороны показывает как можно тот или иной элемент встроить в программный модуль, с другой стороны посмотреть, как выглядит и работает та или иная компонента. Теперь нужно научиться организовывать взаимодействие между этими элементами. Этому посвящена следующая глава, где приведены примеры приложений, разработанных на основе Kivy и KivyMD.