Разработка кроссплатформенных приложений на Kivy
Основы создания приложения на Kivy
Вопрос: Как создать минимальное приложение с кнопкой, изменяющей текст?
Наиболее эффективный способ включает использование класса App и компоновки BoxLayout. Ниже приведен код, который создает окно с меткой и кнопкой. При нажатии на кнопку текст метки меняется.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
class MyApp(App):
def build(self):
layout = BoxLayout(orientation='vertical')
self.label = Label(text='Привет, Kivy!')
btn = Button(text='Нажми меня', on_press=self.on_button_press)
layout.add_widget(self.label)
layout.add_widget(btn)
return layout
def on_button_press(self, instance):
self.label.text = 'Кнопка нажата!'
if __name__ == '__main__':
MyApp().run()
Kivy python приложения (создание приложений на kivy с python)
Пояснение: класс MyApp наследуется от App. Метод build возвращает корневой виджет. BoxLayout располагает дочерние элементы вертикально. Обработчик on_button_press привязан к событию on_press кнопки. Изменение текста метки происходит через свойство text.
Типичные проблемы и их решения:
- Ошибка импорта: если Kivy не установлен, следует выполнить
pip install kivy. - Версия Python: Kivy поддерживает Python 3.7+.
- Имя файла: не следует называть файл
kivy.py, чтобы избежать конфликта импорта. - Зависание приложения: если код содержит бесконечный цикл, следует использовать
Clockдля периодических задач.
Вопрос: Как использовать другие компоновки, например FloatLayout, для произвольного расположения элементов?
Вариант с FloatLayout позволяет задавать позицию виджетов в процентах или абсолютных координатах. В следующем примере метка и кнопка располагаются в разных углах окна.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
class FloatApp(App):
def build(self):
layout = FloatLayout()
label = Label(text='Верхний левый угол',
size_hint=(0.3, 0.2),
pos_hint={'x': 0, 'top': 1})
btn = Button(text='Кнопка внизу',
size_hint=(0.4, 0.1),
pos_hint={'center_x': 0.5, 'y': 0})
layout.add_widget(label)
layout.add_widget(btn)
return layout
if __name__ == '__main__':
FloatApp().run()
Пояснение: size_hint задает относительный размер (доли от родителя), pos_hint определяет привязку к сторонам. Например, {'x':0, 'top':1} означает левый верхний угол. Такой подход удобен для адаптивных интерфейсов.
Проблемы и решения:
- Элементы накладываются друг на друга: проверка значений
pos_hintиsize_hint. - Не видно кнопку, если
yравно нулю: добавление отступа или использование'y': 0.1. - Некорректная работа на разных разрешениях: рекомендуется задавать
size_hintв долях, а не фиксированные пиксели.
Расширенные примеры приложений на Kivy
Пример 1: Текстовое поле и отображение ввода
Приложение с TextInput, которое обновляет Label при каждом изменении текста. Используется привязка к событию on_text.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
class TextInputApp(App):
def build(self):
layout = BoxLayout(orientation='vertical')
self.label = Label(text='Введите текст')
text_input = TextInput(text='', multiline=False)
text_input.bind(text=self.on_text_change)
layout.add_widget(self.label)
layout.add_widget(text_input)
return layout
def on_text_change(self, instance, value):
self.label.text = value
if __name__ == '__main__':
TextInputApp().run()
Результат: окно с полем ввода и меткой. При вводе символов метка немедленно отображает введенный текст. Если поле пустое, метка показывает пустую строку.
Пример 2: Слайдер для управления значением
Использование Slider и Label для отображения текущего значения. Слайдер передает значение от 0 до 100.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.slider import Slider
class SliderApp(App):
def build(self):
layout = BoxLayout(orientation='vertical', padding=20)
self.label = Label(text='50')
slider = Slider(min=0, max=100, value=50)
slider.bind(value=self.on_slider_value)
layout.add_widget(self.label)
layout.add_widget(slider)
return layout
def on_slider_value(self, instance, value):
self.label.text = str(int(value))
if __name__ == '__main__':
SliderApp().run()
Результат: окно с ползунком и меткой. Перемещение ползунка изменяет число на метке от 0 до 100.
Пример 3: Анимация кнопки
С помощью класса Animation можно плавно перемещать виджет. В примере кнопка двигается по экрану.
from kivy.app import App
from kivy.uix.button import Button
from kivy.animation import Animation
from kivy.uix.floatlayout import FloatLayout
class AnimApp(App):
def build(self):
layout = FloatLayout()
self.btn = Button(text='Двигайся!', size_hint=(0.2, 0.1),
pos_hint={'center_x': 0.5, 'center_y': 0.5})
self.btn.bind(on_press=self.start_animation)
layout.add_widget(self.btn)
return layout
def start_animation(self, instance):
anim = Animation(x=200, y=300, duration=2) + Animation(x=100, y=100, duration=2)
anim.start(instance)
if __name__ == '__main__':
AnimApp().run()
Результат: окно с кнопкой в центре. При нажатии кнопка плавно перемещается сначала в точку (200,300), затем в (100,100). Анимация повторяется при каждом нажатии.
Пример 4: Использование KV языка для разделения представления и логики
KV язык позволяет описывать интерфейс декларативно. Код Python становится чище. Пример простого приложения с кнопкой и меткой.
# main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class MainLayout(BoxLayout):
def change_label(self):
self.ids.my_label.text = 'Новый текст'
class KVApp(App):
def build(self):
return MainLayout()
if __name__ == '__main__':
KVApp().run()
# main.kv
<MainLayout>:
orientation: 'vertical'
Label:
id: my_label
text: 'Исходный текст'
font_size: '20sp'
Button:
text: 'Изменить'
on_press: root.change_label()
Результат: окно с меткой и кнопкой. При нажатии кнопки текст метки меняется на «Новый текст». KV файл должен находиться в той же папке и иметь имя, соответствующее имени класса App (KVApp -> kvapp.kv или main.kv, если App называется KVApp).