ARCHITECTURE
Widget Kv Language
Cache Clock Gesture Event Loop Properties
Core Providers
Window
Text
Image
Video
Audio
Graphics
Vertex Buffer
Frame Buffer
Texture
Shader
Instructions
Inputs
Motion Event
Post Processing
(double tab,
Dejitter, …)
Pygame PIL Gstreamer
FFMpeg SDL Cairo
GLES API GLEW
MouseTUIO WM_Touch
Mac TouchMTDev HIDInput
App brought to foreground
After process is killed (Android/iOS)
Kivy bootstrap for Android/iOS
Python start, run()
build()
on_start()
Apps functionson_resume()
Extenal App/OS or internal
function pauses App
on_pause()
Save your work here.
Resume is not guaranteed.
on_stop()
Kivy window destroyed
Python stop
on_pause()
Resume?
return True
return False
NoYes
LIFECYCLE
EVENT LOOP
Clock Events Loop
Filesystem
Network
Process
Other
Motion Events
Post Processing
(double tab, swipe, ...)
Input Processing
Event
Dispatcher
Dispatch Input Events
Custom Events
Property Events
Window Events
GUI
Touch
Mouse
Keyboard
Joystick
Other
Input Kivy Main Thread
Non GUI
Operations
(may run in
dedicated thread)
Main
Loop
EventDispatcher
App
Widget
Widgets are self-contained
and organized as tree
Animation
Clock
MotionEvent
Layout
Controls size and
position of it's children
FloatLayout
BoxLayout
GridLayout
ButtonBehavior
CoverBehavior
DragBehavior
behaviors
...
Button
Switch
Slider
Popup
...
uix
graphics
Widget representation is done using canvas, graphics
instructions are applied to it
ContextInstruction VertexInstruction
Color
Rotate
Scale
...
Triangle
Rectangle
Ellipse
...
Kv Language
The KV language (sometimes called kvlang, or kivy language),
allows you to create your widget tree in a declarative way
and to bind widget properties to each other or to callbacks in a
natural manner.
...
OBJECTS
Mixin Classes for Widgets
APPLICATION
import kivy
# replace with your current kivy version
kivy.require('1.9.1')
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
# MyApp inherits from App object
def build(self):
# build returns the root widget
return Label(text='Hello world')
if __name__ == '__main__':
MyApp().run()
REPETITIVE EVENTS
from kivy.clock import Clock
def my_callback(dt):
# ``dt`` is delta time
print('My callback is called'.format(dt))
# call ``my_callback`` X times per second
event = Clock.schedule_interval(my_callback, 1 / 30.)
# unscedule can be done by either using
event.cancel()
# or
Clock.unschedule(event)
def my_callback(dt):
# if repetitive callback returns False, it gets unscheduled as well
if some_condition:
return False
# regular processing
Clock.schedule_interval(my_callback, 1 / 30.)
ONE-TIME EVENTS
from kivy.clock import Clock
def my_callback(dt):
print('My callback is called'.format(dt))
# call ``my_callback`` once in one second
Clock.schedule_once(my_callback, 1)
The second argument is the amount of time to wait before calling the function,
in seconds. However, you can achieve some other results with special values
for the second argument:
● If X is greater than 0, the callback will be called in X seconds
● If X is 0, the callback will be called after the next frame
● If X is -1, the callback will be called before the next frame
INPUT AND PROPERTY EVENTS
from kivy.uix.widget import Widget
from kivy.properties import ListProperty
class CustomBtn(Widget):
# it's possible to bind to kivy property changes
pressed = ListProperty([0, 0])
def on_touch_down(self, touch):
# event handler for regular touch events
if self.collide_point(*touch.pos):
# setting pressed property triggers property event
self.pressed = touch.pos
# return True to indicate event consumed
return True
# delegate touch event to super class
return super(CustomBtn, self).on_touch_down(touch)
def on_pressed(self, instance, pos):
# event handler triggered if ``pressed`` property changed
print('pressed at {pos}'.format(pos=pos))
CUSTOM EVENTS
from kivy.event import EventDispatcher
class MyEventDispatcher(EventDispatcher):
def __init__(self, **kw):
# register custom event
self.register_event_type('on_test')
super(MyEventDispatcher, self).__init__(**kw)
def do_something(self, value):
# when do_something is called, the 'on_test' event will be
# dispatched with the value
self.dispatch('on_test', value)
def on_test(self, *args):
# default event handler
print('I am dispatched'.format(args))
def my_callback(value, *args):
print('Hello, I got an event!'.format(args))
ev = MyEventDispatcher() # instanciate ``MyEventDispatcher``
ev.bind(on_test=my_callback) # bind ``my_callback`` to ``on_test``
ev.do_something('test') # ``do_something`` dispatches ``on_test``
WIDGET TREE
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
# create widget and add children
layout = BoxLayout(padding=10)
button = Button(text='My first button')
layout.add_widget(button)
# remove child from widget
layout.remove_widget(button)
# clear children
layout.clear_widgets()
# traversing the tree, iterate widget children
for child in layout.children:
print(child)
# traversing the tree, access parent widget
child = layout.children[0]
Layout = child.parent
# setting a z-index for a child widget
layout.add_widget(widget, index)
KV LANGUAGE
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string('''
<CustomLayout>
Button:
text: 'Hello World!!'
size_hint: .5, .5
pos_hint: {'center_x': .5, 'center_y': .5}
''')
class CustomLayout(FloatLayout):
pass
As your application grow more complex, it’s common that the construction of widget
trees and explicit declaration of bindings, becomes verbose and hard to maintain.
The KV Language is a attempt to overcome these short-comings.
In the example above KV code is defined inside python module as docstring passed
to Builder.load_string. KV code can also be contained in a separate
file which can be loaded by using Builder.load_file('path/to/file.kv')
GRAPHICS
class MyWidget(Widget):
def __init__(self, **kw):
super(MyWidget, self).__init__(**kw)
with self.canvas:
# add your instruction for main canvas here
Color(1, 0, .4, mode='rgb')
Line(points=(x1, y1, x2, y2, x3, y3))
with self.canvas.before:
# you can use this to add instructions rendered before
with self.canvas.after:
# you can use this to add instructions rendered after
MyWidget:
canvas:
Color:
rgba: 1, .3, .8, .5
Line:
points: zip(self.data.x, self.data.y)
Graphics instructions in Python
Graphics instructions in KV language