Разработка кроссплатформенных приложений на Kivy

Раздел: Python -> Разработка мобильных приложений

Основы создания приложения на 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).

Создание приложений на Kivy с Python - comments

En
Kivy python приложения (python)