ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 06.12.2023
Просмотров: 156
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
В данном коде вызывается button.bind(), а событие on_press ссылается на MainApp.on_press_button().Этот метод неявно принимает экземпляр виджета, который является самим объектом кнопки. Сообщение будет выводиться на stdout всякий раз при нажатии пользователем на кнопку.Использование языка дизайна KVKivy предоставляет язык дизайна KV, что можно использовать в приложениях Kivy. Язык KV позволяет отделить дизайн интерфейса от логики приложения. Он придерживается принципа разделения ответственности и является частью архитектурного паттерна Модель-Представление-Контроллер (Model-View-Controller). Предыдущий пример можно обновить, используя язык KV:Python
С первого взгляда данный код может показаться несколько странным, так как кнопка Button создается без указания атрибутов или привязывания к ним событий. Здесь Kivy автоматически ищет файл с таким же названием, что и у класса, только строчными буквами и без части App в названии класса.В данном случае названием класса является ButtonApp, поэтому Kivy будет искать файл button.kv. Если такой файл существует, и он также форматирован должным образом, тогда Kivy использует его при загрузке UI. Попробуйте создать такой файл и добавить следующий код:Python
Действия каждой строки:
импорт модулей Python в KV, создавая динамичные классы, и это далеко не предел. Ознакомиться с полным перечнем его возможностей можно в гиде Kivy по языку KV.Теперь мы можем приступить к созданию настоящего рабочего приложения.Создание приложения Kivy PythonСоздание чего-то полезное несомненно является отличным способом выучить новый навык. Учитывая данное утверждение, давайте используем Kivy при создании калькулятора, который будет поддерживать следующие операции:
Калькулятор работает следующим образом:
В строках с 33 по 37 создается кнопка равно (=) и привязывается к обработчику событий, после чего она добавляется к main_layout.
Далее создается обработчик событий .on_button_press(). Код будет выглядеть следующим образом:
Python
Почти все виджеты приложения вызывают .on_button_press(). Это работает следующим образом:
Последней частью кода будет .on_solution():Python
Здесь берется текущий текст из solution и используется встроенный в Python eval() для исполнения. Если пользователь создал формулу вроде 1+2, тогда eval() запустит код и вернет результат. В конце результат устанавливается как новое значение виджета solution.На заметку: порой eval() бывает опасным, так как он может запустить произвольный код. Многие разработчики избегают его использование именно по этой причине. Тем не менее, ввиду задействования только целых чисел, операторов и точки в качестве вводных данных для eval(), в данном контексте его можно использовать безопасно.При запуске данного кода на рабочем столе компьютера приложение будет выглядеть следующим образом:Полный текст кода примера калькулятора представлен ниже:Python
Пришло время разместить приложение в Google Play или в AppStore!Создаем apk приложения для Android на PythonПо завершении составления кода вы можете поделиться своим приложением с другими. Хорошим способом сделать это может стать превращение вашего кода в приложения для смартфона на Android. Для этого вначале нужно установить пакет buildozer через pip:Shell
Затем создается новая папка, после чего нужно перейти в нее через терминал. Затем выполняется следующая команда:Shell
После этого создается файл buildozer.spec, который будет использован для конфигурации сборки. К примеру, первые две строчки файла спецификации можно редактировать следующим образом:Shell
Не бойтесь посмотреть оставшуюся часть файла для выяснения того, что еще можно поменять.На данный момент приложение почти готово к сборке, однако для начала нужно установить зависимости для buildozer. После их установки скопируйте ваше приложение калькулятора в новую папку и переименуйте его в main.py. Этого требует buildozer. Если файл будет назван неверно, тогда процесс сборки завершится неудачей.Теперь можно запустить следующую команду:Shell
Этап сборки займет время! На моем компьютере на это ушло около 15-20 минут. Здесь все зависит от вашего железа, так что времени может потребоваться еще больше. Расслабьтесь, налейте чашечку кофе или прогуляйтесь. Buildozer скачает те элементы Android SDK, которые нужны для процесса сборки. Если все идет по плану, тогда в папке bin появится файл под названием, напоминающим что-то вроде kvcalc-0.1-debug.apk.Далее требуется связать телефон Android с компьютером и перенести туда файл apk. Затем откройте менеджер файлов телефона и кликните на файл apk. Android должен спросить, хотите ли вы установить приложение. Есть вероятность появления предупреждения, ведь приложение было скачано не из Google Play
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | from kivy.app import App from kivy.uix.button import Button class ButtonApp(App): def build(self): return Button() def on_press_button(self): print('Вы нажали на кнопку!') if __name__ == '__main__': app = ButtonApp() app.run() |
| 1 2 3 4 5 | |
-
Строка 1 соответствует вызову Button в коде Python. Kivy должен осмотреть инициализированный объект для определения кнопки; -
Строка 2 устанавливает text кнопки; -
Строка 3 устанавливает ширину и высоту при помощи size_hint; -
Строка 4 устанавливает позицию кнопки через pos_hint; -
Строка 5 устанавливает обработчик событий on_press. Для указания Kivy места обработчика событий используется app.on_press_button(). Здесь Kivy будет искать метод .on_press_button() в классе Application.
импорт модулей Python в KV, создавая динамичные классы, и это далеко не предел. Ознакомиться с полным перечнем его возможностей можно в гиде Kivy по языку KV.Теперь мы можем приступить к созданию настоящего рабочего приложения.Создание приложения Kivy PythonСоздание чего-то полезное несомненно является отличным способом выучить новый навык. Учитывая данное утверждение, давайте используем Kivy при создании калькулятора, который будет поддерживать следующие операции:
-
Сложение; -
Вычитание; -
Умножение; -
Деление.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.textinput import TextInput class MainApp(App): def build(self): self.operators = ["/", "*", "+", "-"] self.last_was_operator = None self.last_button = None main_layout = BoxLayout(orientation="vertical") self.solution = TextInput( multiline=False, readonly=True, halign="right", font_size=55 ) main_layout.add_widget(self.solution) buttons = [ ["7", "8", "9", "/"], ["4", "5", "6", "*"], ["1", "2", "3", "-"], [".", "0", "C", "+"], ] for row in buttons: h_layout = BoxLayout() for label in row: button = Button( text=label, pos_hint={"center_x": 0.5, "center_y": 0.5}, ) button.bind(on_press=self.on_button_press) h_layout.add_widget(button) main_layout.add_widget(h_layout) equals_button = Button( text="=", pos_hint={"center_x": 0.5, "center_y": 0.5} ) equals_button.bind(on_press=self.on_solution) main_layout.add_widget(equals_button) return main_layout |
-
В строках с 8 по 10 создается список operators и несколько полезных значений, last_was_operator и last_button, которые будут использованы чуть позже. -
В строках с 11 по 15 создается лейаут верхнего уровня main_layout, к нему также добавляется виджет только для чтения TextInput. -
В строках с 16 по 21 создается вложенный список из списков, где есть большая часть кнопок для калькулятора. -
В строке 22 начинается цикл for для кнопок. Для каждого вложенного списка делается следующее:
-
В строке 23 создается BoxLayout с горизонтальной ориентацией. -
В строке 24 начинается еще один цикл for для элементов вложенного списка. -
В строках с 25 по 39 создаются кнопки для ряда и связываются обработчиком событий, после чего кнопки добавляются к горизонтальному BoxLayout из строки 23. -
В строке 31 этот лейаут добавляется к main_layout.
В строках с 33 по 37 создается кнопка равно (=) и привязывается к обработчику событий, после чего она добавляется к main_layout.
Далее создается обработчик событий .on_button_press(). Код будет выглядеть следующим образом:
Python
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def on_button_press(self, instance): current = self.solution.text button_text = instance.text if button_text == "C": # Очистка виджета с решением self.solution.text = "" else: if current and ( self.last_was_operator and button_text in self.operators): # Не добавляйте два оператора подряд, рядом друг с другом return elif current == "" and button_text in self.operators: # Первый символ не может быть оператором return else: new_text = current + button_text self.solution.text = new_text self.last_button = button_text self.last_was_operator = self.last_button in self.operators |
Почти все виджеты приложения вызывают .on_button_press(). Это работает следующим образом:
-
Строка 41 принимает аргумент instance, в результате чего можно узнать, какой виджет вызвал функцию. -
Строки между 42 и 43 извлекают и хранят значения solution и text кнопки. -
Строки c 45 по 47 проверяют, на какую кнопку нажали. Если пользователь нажимает с, тогда очищается solution. В противном случае используется утверждение else. -
Строка 49 проверяет, было ли у решения предыдущее значение. -
Строки с 50 по 52 проверяют, была ли последняя нажатая кнопка оператором. Если да, тогда solution обновляться не будет. Это необходимо для предотвращения создания двух операций в одном ряду. К примеру, 1 * / будет недействительным утверждением. -
Строки с 53 по 55 проверяют, является ли первый символ оператором. Если да, тогда solution обновляться не будет, так как первое значение не может быть значением оператора. -
Строки с 56 по 58 переходят к условию else. Если никакое из предыдущих значений не найдено, тогда обновляется solution. -
Строка 59 устанавливает last_button к метке последней нажатой кнопки. -
Строка 60 устанавливает last_was_operator к значению True или False в зависимости от того, был символ оператором или нет.
Последней частью кода будет .on_solution():Python
| 1 2 3 4 5 | def on_solution(self, instance): text = self.solution.text if text: solution = str(eval(self.solution.text)) self.solution.text = solution |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.textinput import TextInput class MainApp(App): def build(self): self.operators = ["/", "*", "+", "-"] self.last_was_operator = None self.last_button = None main_layout = BoxLayout(orientation="vertical") self.solution = TextInput( multiline=False, readonly=True, halign="right", font_size=55 ) main_layout.add_widget(self.solution) buttons = [ ["7", "8", "9", "/"], ["4", "5", "6", "*"], ["1", "2", "3", "-"], [".", "0", "C", "+"], ] for row in buttons: h_layout = BoxLayout() for label in row: button = Button( text=label, pos_hint={"center_x": 0.5, "center_y": 0.5}, ) button.bind(on_press=self.on_button_press) h_layout.add_widget(button) main_layout.add_widget(h_layout) equals_button = Button( text="=", pos_hint={"center_x": 0.5, "center_y": 0.5} ) equals_button.bind(on_press=self.on_solution) main_layout.add_widget(equals_button) return main_layout def on_button_press(self, instance): current = self.solution.text button_text = instance.text if button_text == "C": # Очистка виджета с решением self.solution.text = "" else: if current and ( self.last_was_operator and button_text in self.operators): # Не добавляйте два оператора подряд, рядом друг с другом return elif current == "" and button_text in self.operators: # Первый символ не может быть оператором return else: new_text = current + button_text self.solution.text = new_text self.last_button = button_text self.last_was_operator = self.last_button in self.operators def on_solution(self, instance): text = self.solution.text if text: solution = str(eval(self.solution.text)) self.solution.text = solution if __name__ == "__main__": app = MainApp() app.run() |
Пришло время разместить приложение в Google Play или в AppStore!Создаем apk приложения для Android на PythonПо завершении составления кода вы можете поделиться своим приложением с другими. Хорошим способом сделать это может стать превращение вашего кода в приложения для смартфона на Android. Для этого вначале нужно установить пакет buildozer через pip:Shell
| 1 | $ pip install buildozer |
| 1 | $ buildozer init |
| 1 2 3 4 5 6 7 8 9 10 | [app] # (str) Название вашего приложения title = KvCalc # (str) Название упаковки package.name = kvcalc # (str) Домен упаковки (нужен для упаковки android/ios) package.domain = org.kvcalc |
| 1 | $ buildozer -v android debug |