Showcase of Kivy Features¶
This showcases many features of Kivy. You should see a menu bar across the top with a demonstration area below. The first demonstration is the accordion layout. You can see, but not edit, the kv language code for any screen by pressing the bug or ‘show source’ icon. Scroll through the demonstrations using the left and right icons in the top right or selecting from the menu bar.
The file showcase.kv describes the main container, while each demonstration pane is described in a separate .kv file in the data/screens directory. The image data/background.png provides the gradient background while the icons in data/icon directory are used in the control bar. The file data/faust_github.jpg is used in the Scatter pane. The icons are from http://www.gentleface.com/free_icon_set.html and licensed as Creative Commons — Attribution and Non-commercial Use Only; they sell a commercial license.
The file android.txt is used to package the application for use with the Kivy Launcher Android application. For Android devices, you can copy/paste this directory into /sdcard/kivy/showcase on your Android device.
File demo/showcase/main.py¶
''' Showcase of Kivy Features ========================= This showcases many features of Kivy. You should see a menu bar across the top with a demonstration area below. The first demonstration is the accordion layout. You can see, but not edit, the kv language code for any screen by pressing the bug or 'show source' icon. Scroll through the demonstrations using the left and right icons in the top right or selecting from the menu bar. The file showcase.kv describes the main container, while each demonstration pane is described in a separate .kv file in the data/screens directory. The image data/background.png provides the gradient background while the icons in data/icon directory are used in the control bar. The file data/faust_github.jpg is used in the Scatter pane. The icons are from `http://www.gentleface.com/free_icon_set.html` and licensed as Creative Commons - Attribution and Non-commercial Use Only; they sell a commercial license. The file android.txt is used to package the application for use with the Kivy Launcher Android application. For Android devices, you can copy/paste this directory into /sdcard/kivy/showcase on your Android device. ''' from time import time from kivy.app import App from os.path import dirname, join from kivy.lang import Builder from kivy.properties import NumericProperty, StringProperty, BooleanProperty,\ ListProperty from kivy.clock import Clock from kivy.animation import Animation from kivy.uix.screenmanager import Screen class ShowcaseScreen(Screen): fullscreen = BooleanProperty(False) def add_widget(self, *args, **kwargs): if 'content' in self.ids: return self.ids.content.add_widget(*args, **kwargs) return super(ShowcaseScreen, self).add_widget(*args, **kwargs) class ShowcaseApp(App): index = NumericProperty(-1) current_title = StringProperty() time = NumericProperty(0) show_sourcecode = BooleanProperty(False) sourcecode = StringProperty() screen_names = ListProperty([]) hierarchy = ListProperty([]) def build(self): self.title = 'hello world' Clock.schedule_interval(self._update_clock, 1 / 60.) self.screens = <> self.available_screens = sorted([ 'Buttons', 'ToggleButton', 'Sliders', 'ProgressBar', 'Switches', 'CheckBoxes', 'TextInputs', 'Accordions', 'FileChoosers', 'Carousel', 'Bubbles', 'CodeInput', 'DropDown', 'Spinner', 'Scatter', 'Splitter', 'TabbedPanel + Layouts', 'RstDocument', 'Popups', 'ScreenManager']) self.screen_names = self.available_screens curdir = dirname(__file__) self.available_screens = [join(curdir, 'data', 'screens', '<>.kv'.format(fn).lower()) for fn in self.available_screens] self.go_next_screen() def on_pause(self): return True def on_resume(self): pass def on_current_title(self, instance, value): self.root.ids.spnr.text = value def go_previous_screen(self): self.index = (self.index - 1) % len(self.available_screens) screen = self.load_screen(self.index) sm = self.root.ids.sm sm.switch_to(screen, direction='right') self.current_title = screen.name self.update_sourcecode() def go_next_screen(self): self.index = (self.index + 1) % len(self.available_screens) screen = self.load_screen(self.index) sm = self.root.ids.sm sm.switch_to(screen, direction='left') self.current_title = screen.name self.update_sourcecode() def go_screen(self, idx): self.index = idx self.root.ids.sm.switch_to(self.load_screen(idx), direction='left') self.update_sourcecode() def go_hierarchy_previous(self): ahr = self.hierarchy if len(ahr) == 1: return if ahr: ahr.pop() if ahr: idx = ahr.pop() self.go_screen(idx) def load_screen(self, index): if index in self.screens: return self.screens[index] screen = Builder.load_file(self.available_screens[index]) self.screens[index] = screen return screen def read_sourcecode(self): fn = self.available_screens[self.index] with open(fn) as fd: return fd.read() def toggle_source_code(self): self.show_sourcecode = not self.show_sourcecode if self.show_sourcecode: height = self.root.height * .3 else: height = 0 Animation(height=height, d=.3, t='out_quart').start( self.root.ids.sv) self.update_sourcecode() def update_sourcecode(self): if not self.show_sourcecode: self.root.ids.sourcecode.focus = False return self.root.ids.sourcecode.text = self.read_sourcecode() self.root.ids.sv.scroll_y = 1 def showcase_floatlayout(self, layout): def add_button(*t): if not layout.get_parent_window(): return if len(layout.children) > 5: layout.clear_widgets() layout.add_widget(Builder.load_string(''' #:import random random.random Button: size_hint: random(), random() pos_hint: text: 'size_hint x: <> y: <>\\n pos_hint x: <> y: <>'.format(\ self.size_hint_x, self.size_hint_y, self.pos_hint['x'],\ self.pos_hint['y']) ''')) Clock.schedule_once(add_button, 1) Clock.schedule_once(add_button) def showcase_boxlayout(self, layout): def add_button(*t): if not layout.get_parent_window(): return if len(layout.children) > 5: layout.orientation = 'vertical'\ if layout.orientation == 'horizontal' else 'horizontal' layout.clear_widgets() layout.add_widget(Builder.load_string(''' Button: text: self.parent.orientation if self.parent else '' ''')) Clock.schedule_once(add_button, 1) Clock.schedule_once(add_button) def showcase_gridlayout(self, layout): def add_button(*t): if not layout.get_parent_window(): return if len(layout.children) > 15: layout.rows = 3 if layout.rows is None else None layout.cols = None if layout.rows == 3 else 3 layout.clear_widgets() layout.add_widget(Builder.load_string(''' Button: text: 'rows: <>\\ncols: <>'.format(self.parent.rows, self.parent.cols)\ if self.parent else '' ''')) Clock.schedule_once(add_button, 1) Clock.schedule_once(add_button) def showcase_stacklayout(self, layout): orientations = ('lr-tb', 'tb-lr', 'rl-tb', 'tb-rl', 'lr-bt', 'bt-lr', 'rl-bt', 'bt-rl') def add_button(*t): if not layout.get_parent_window(): return if len(layout.children) > 11: layout.clear_widgets() cur_orientation = orientations.index(layout.orientation) layout.orientation = orientations[cur_orientation - 1] layout.add_widget(Builder.load_string(''' Button: text: self.parent.orientation if self.parent else '' size_hint: .2, .2 ''')) Clock.schedule_once(add_button, 1) Clock.schedule_once(add_button) def showcase_anchorlayout(self, layout): def change_anchor(self, *l): if not layout.get_parent_window(): return anchor_x = ('left', 'center', 'right') anchor_y = ('top', 'center', 'bottom') if layout.anchor_x == 'left': layout.anchor_y = anchor_y[anchor_y.index(layout.anchor_y) - 1] layout.anchor_x = anchor_x[anchor_x.index(layout.anchor_x) - 1] Clock.schedule_once(change_anchor, 1) Clock.schedule_once(change_anchor, 1) def _update_clock(self, dt): self.time = time() if __name__ == '__main__': ShowcaseApp().run()
File demo/showcase/showcase.kv¶
1#:kivy 1.8.0 2#:import KivyLexer kivy.extras.highlight.KivyLexer 3#:import Factory kivy.factory.Factory 4 5 6 background_color: .4, .4, .4, 1 7 8 9 canvas.before: 10 Color: 11 rgba: 0.128, 0.128, 0.128, 1 12 Rectangle: 13 size: self.size 14 pos: self.pos 15 border: 27, 20, 12, 12 16 background_normal: 'atlas://data/images/defaulttheme/action_group' 17 option_cls: Factory.ActionSpinnerOptions 18 19 : 20 on_size: self.width = '220dp' 21 22 : 23 ScrollView: 24 do_scroll_x: False 25 do_scroll_y: False if root.fullscreen else (content.height > root.height - dp(16)) 26 AnchorLayout: 27 size_hint_y: None 28 height: root.height if root.fullscreen else max(root.height, content.height) 29 GridLayout: 30 id: content 31 cols: 1 32 spacing: '8dp' 33 padding: '8dp' 34 size_hint: (1, 1) if root.fullscreen else (.8, None) 35 height: self.height if root.fullscreen else self.minimum_height 36 37 38BoxLayout: 39 orientation: 'vertical' 40 41 canvas.before: 42 Color: 43 rgb: .6, .6, .6 44 Rectangle: 45 size: self.size 46 source: 'data/background.png' 47 48 ActionBar: 49 50 ActionView: 51 id: av 52 ActionPrevious: 53 with_previous: (False if sm.current_screen.name == 'button' else True) if sm.current_screen else False 54 title: 'Showcase' + ('' if not app.current_title else ' - <>'.format(app.current_title)) 55 on_release: app.go_hierarchy_previous() 56 57 ActionSpinner: 58 id: spnr 59 important: True 60 text: 'Jump to Screen' 61 values: app.screen_names 62 on_text: 63 if sm.current != args[1]:\ 64 idx = app.screen_names.index(args[1]);\ 65 app.go_screen(idx) 66 ActionToggleButton: 67 text: 'Toggle sourcecode' 68 icon: 'data/icons/bug.png' 69 on_release: app.toggle_source_code() 70 ActionButton: 71 text: 'Previous screen' 72 icon: 'data/icons/chevron-left.png' 73 on_release: app.go_previous_screen() 74 75 ActionButton: 76 text: 'Next screen' 77 icon: 'data/icons/chevron-right.png' 78 on_release: app.go_next_screen() 79 important: True 80 81 ScrollView: 82 id: sv 83 size_hint_y: None 84 height: 0 85 86 CodeInput: 87 id: sourcecode 88 lexer: KivyLexer() 89 text: app.sourcecode 90 readonly: True 91 size_hint_y: None 92 font_size: '12sp' 93 height: self.minimum_height 94 95 ScreenManager: 96 id: sm 97 on_current_screen: 98 spnr.text = args[1].name 99 idx = app.screen_names.index(args[1].name) 100 if idx > -1: app.hierarchy.append(idx)
Image demo/showcase/data/background.png¶
File demo/showcase/android.txt¶
1title=Showcase 2author=Kivy team 3orientation=landscape
Kivy — Создание мобильных приложений на Python
В наши дни каждый разработчик может столкнуться с необходимостью работы над мобильным или веб-приложением на Python. В Python нет встроенных инструментов для мобильных устройств, тем не менее существуют пакеты, которые можно использовать для создания мобильных приложений. Это Kivy, PyQt и даже библиотека Toga от Beeware.
Библиотеки являются основными элементами мобильного мира Python. Однако, говоря о Kivy, нельзя игнорировать преимущества данного фреймворка при работе с мобильными приложениями. Внешний вид приложения автоматически подстраивается под все платформы, разработчику при этом не нужно компилировать код после каждой поправки. Кроме того, здесь для создания приложений можно использовать чистый синтаксис Python.
В руководстве будут разобраны следующие темы:
- Работа с виджетами Kivy;
- Планировка UI и лейауты;
- Добавление событий;
- Использование языка KV;
- Создание приложения-калькулятора;
- Упаковка приложения для iOS, Android, Windows и macOS.
Разбор данного руководства предполагает, что читатель знаком с объектно-ориентированным программированием. Для введения в курс дела можете просмотреть статью об Объектно-ориентированном программировании (ООП) в Python 3.
Принципы работы фреймворка Kivy Python
Kivy был создан в 2011 году. Данный кросс-платформенный фреймворк Python работает на Windows, Mac, Linux и Raspberry Pi. В дополнение к стандартному вводу через клавиатуру и мышь он поддерживает мультитач. Kivy даже поддерживает ускорение GPU своей графики, что во многом является следствием использования OpenGL ES2. У проекта есть лицензия MIT, поэтому библиотеку можно использовать бесплатно и вкупе с коммерческим программным обеспечением.
Во время разработки приложения через Kivy создается интуитивно понятный интерфейс (Natural user Interface), или NUI. Его главная идея в том, чтобы пользователь мог легко и быстро приспособиться к программному обеспечению без чтения инструкций.
Kivy не задействует нативные элементы управления, или виджеты. Все его виджеты настраиваются. Это значит, что приложения Kivy будут выглядеть одинаково на всех платформах. Тем не менее, это также предполагает, что внешний вид вашего приложения будет отличаться от нативных приложений пользователя. Это может стать как преимуществом, так и недостатком, все зависит от аудитории.
Установка Kivy
У Kivy есть множество зависимостей, поэтому лучше устанавливать его в виртуальную среду Python. Можно использовать встроенную библиотеку Python venv или же пакет virtualenv.
Виртуальная среда Python создается следующим образом: