2017/06/20 update
It appeared in the translation of the official manual. After that, make corrections using the links below. The fix is compatible with the latest version 1.10 of kivy.
A translation of the Kivy API reference Kivy Language. [Programming Guide (translated) »Kv language (translated)" (https://pyky.github.io/kivy-doc-ja/guide/lang.html) has an explanation that is not described, so try translating it. I did.
Kivy Language
Module: kivy.langAdded in 1.0.0
Kivy Language is a dedicated language for describing user interfaces and interactions. You can compare this language with Qt's QML (http://qt.nokia.com), but it contains new concepts such as Rule definitions (much like CSS) and templates.
Changed in version 1.7.0: Builder does not perform canvas representation in real time. Pack all the expressions that need to be executed first, dispatch the input, and then execute it just before drawing the frame. If you want to force the canvas drawing, call Builder.sync. . *
Includes experimental profiling tools for kv lang. You can activate it by setting the environment variable KIVY_PROFILE_LANG = 1. After that, an html file named builder_stats.html will be generated. *
Kivy Language consists of several configurations available.
Rule Rule is similar to CSS rule. Rules are applied to a particular widget (or its class) in the widget tree and are modified in a particular way. You can use Rules to specify interactive behavior, and Rules to add a graphical representation of the widget you want to apply. You can use the cls attribute (eg cls = MyTestWidget) to target a particular class of widgets (similar to the CSS concept of a class).
Root Widget You can use Kivy Language to create the entire user interface. The kv file should contain at most one root widget.
Dynamic Classes Dynamic Class (introduced in version 1.7.0) allows you to quickly create new widgets and rules without declaration on the Python file side.
Templates (deprecated) (Introduced in version 1.0.5 and deprecated in version 1.7.0) Templates are used to fill parts of an application, such as styling list content (for example, left icon, right text). I did. Deprecated by Dynamic Class.
Kivy Language files have a .kv file extension.
The contents of the file should always start with the Kivy header. The version should be replaced with the version of Kivy Language you are using. For 1.0:
#:kivy `1.0`
# content here
Content can include Rule definitions, Root Widgets, Dynamic Class definitions, and Templates.
# Syntax of a rule definition. Note that several Rules can share the same
# definition (as in CSS). Note the braces: they are part of the definition.
<Rule1,Rule2>:
# .. definitions ..
<Rule3>:
# .. definitions ..
# Syntax for creating a root widget
RootClassName:
# .. definitions ..
# Syntax for creating a dynamic class
<NewWidget@BaseClass>:
# .. definitions ..
# Syntax for create a template
[TemplateName@BaseClass1,BaseClass2]:
# .. definitions ..
Whether it's a Rule, a Root Widget, a Dynamic Class, or a Template you're defining, the definition looks like this:
# With the braces it's a rule. Without them, it's a root widget.
<ClassName>:
prop1: value1
prop2: value2
canvas:
CanvasInstruction1:
canvasprop1: value1
CanvasInstruction2:
canvasprop2: value2
AnotherClass:
prop3: value1
Where * prop1 * and * prop2 * are properties of * ClassName * and * prop3 * are properties of * AnotherClass *. If the widget does not have a property with the specified name, an ObjectProperty is automatically created and added to the widget.
AnotherClass * is created and added as a child of the * ClassName * instance.
Indentation is important and must be consistent. The space must be a multiple of the space used for the first indented row. Mixing tabs and spaces is not recommended.
Property values must be given on one line (at least for now).
Canvas properties are special. You can graphically represent the current class with graphics instructions.
Below is a simple example of a kv file containing a root widget
#:kivy 1.0
Button:
text: 'Hello world'
Both the load_file () and load_string () methods return the root widget defined in the kv file / string. Also, add the class and template definitions to the Factory for later use.
If you specify a value for a property, that value is evaluated as a Python expression. This expression can be static or dynamic. That is, you can use reserved keywords to use the values of other properties.
self The keyword self refers to "the current instance of the widget":
Button:
text: 'My state is %s' % self.state
root This keyword can only be used in Rule definitions and represents the Rule's root widget (the first instance of Rule).
<MyWidget>:
custom: 'Hello world'
Button:
text: root.custom
app This keyword always refers to your app instance. Same as calling kivy.app.App.get_running_app () in Python.
Label:
text: app.name
args
This keyword can be used in the on_ \ <action > callback. This refers to the arguments passed to the callback.
TextInput:
on_focus: self.insert_text("Focus" if args[1] else "No focus")
ids
The class definition can include an ID that can be used as a keyword.
<MyWidget>:
Button:
id: btn1
Button:
text: 'The state of the other button is %s' % btn1.state
Note that this * id * cannot be used with an instance of widget. It is used exclusively for external references. * id * is a weak reference to the widget, not the widget itself. The widget itself can be accessed with id .__ self__ (btn1 .__ self__ in this case).
When the kv file is processed, a weak reference to all widgets tagged with * id * is added to the * ids * dictionary in root widgets. In other words, following the example above, you can access the button status as follows:
widget = MyWidget()
state = widget.ids["btn1"].state
# Or, as an alternative syntax,
state = widget.ids.btn1.state
Note that the outermost widget applies the kvRule to all internal widgets before the other Rules are applied. That is, if your internal widget contains ids, these ids may not be available in your internal widget's init function.
There are two places in the kv file to accept python statements. After the property, the result of the expression (such as the button text below) and after on_property the property is updated (such as on_state).
In the former case, the expression can only be on one line, newlines cannot be escaped and extended to multiple lines, and a value must be returned. Examples of valid expressions are text: self.state and ('up' for self.state =='normal' else' down').
In the latter case, multiple single-line statements, including multi-line statements that escape newlines, are valid unless you add an indentation level.
Here is an example of a valid statement:
on_press: if self.state == 'normal': print('normal')
on_state:
if self.state == 'normal': print('normal')
else: print('down')
if self.state == 'normal': \
print('multiline normal')
for i in range(10): print(i)
print([1,2,3,4,
5,6,7])
Examples of invalid statements:
on_state:
if self.state == 'normal':
print('normal')
With Kivy Language, you can see that the work is done automatically behind the scenes. You should know that Properties implements the Observer Design Pattern. That is, you can bind your own function to be called when the value of the property changes (that is, passively observe the property for potential changes).
Kivy Language creates a create callback to detect the properties of a value expression and automatically update the properties via the expression when changes occur.
The following is a simple example of this behavior.
Button:
text: str(self.state)
In this example, the parser detects that self.state is a dynamic value (property). You can change the button's state property at any time (when the user touches it). This button should display its own state as text, even if the state changes. To do this, use the Button's state property and use it for the value of the button's text property. This controls the text displayed on the button (which also converts the state to a string representation). The text properties are automatically updated each time the button state changes.
Please remember. The value is a Python expression! So you can do some interesting things like this:
Button:
text: 'Plop world' if self.state == 'normal' else 'Release me!'
The text of the Button changes with the state of the Button. By default, the Button's text is "Plop world", but when you press the Button, the text changes to "Release me!".
More precisely, the Kivy Language parser finds all substrings in Xab format where X is self or root or app or a known id and a and b are properties. Then add and modify the appropriate dependencies. For example, this works as expected.
<IndexedExample>:
beta: self.a.b[self.c.d]
However, due to the expected parser restrictions in the future, you cannot:
<BadExample>:
beta: self.a.b[self.c.d].e.f
Certainly the .e.f part does not follow the expected pattern and is not recognized because the proper dependencies are not set. Instead, you need to introduce an intermediate property to allow the following constraints:
<GoodExample>:
alpha: self.a.b[self.c.d]
beta: self.alpha.e.f
Graphical instructions are a special part of the Kivy language. They are handled by the'canvas' property definition:
Widget:
canvas:
Color:
rgb: (1, 1, 1)
Rectangle:
size: self.size
pos: self.pos
All classes added within the canvas property must derive from the Instruction class. You can't put the Widget class inside the canvas property (widget doesn't make sense as it's not a graphics related instruction).
If you want to take advantage of the theme, you'll be asked the same question as CSS: which Rule was executed first? In this case, Rules are executed in processing order (top-down).
If you want to change the way the button is rendered, you can create your own kv file and add it as follows:
<Button>:
canvas:
Color:
rgb: (1, 0, 0)
Rectangle:
pos: self.pos
size: self.size
Rectangle:
pos: self.pos
size: self.texture_size
texture: self.texture
This will bring up a button with a red background labeled at the bottom left, in addition to all the above Rules. You can use the * Clear * command to clear all the previous steps.
<Button>:
canvas:
Clear
Color:
rgb: (1, 0, 0)
Rectangle:
pos: self.pos
size: self.size
Rectangle:
pos: self.pos
size: self.texture_size
texture: self.texture
Only Rules following the * Clear * command are considered
Dynamic classes
The Dynamic class allows you to quickly create a new widget without first using a Python declaration. The syntax of Dynamic class is similar to Rule, but you need to specify the base class to subclass.
The syntax is as follows:
# Simple inheritance
<NewWidget@Button>:
# kv code here ...
# Multiple inheritance
<NewWidget@ButtonBehavior+Label>:
# kv code here ...
The @ character is used to distinguish the class name from the subclassing class. How much is it in Python.
# Simple inheritance
class NewWidget(Button):
pass
# Multiple inheritance
class NewWidget(ButtonBehavior, Label):
pass
New properties are usually added in Python code and must be declared first. If the property does not exist in the Dynamic class, it will be automatically created as an ObjectProperty (prior to 1.8.0) or a suitable typed property (from 1.8.0).
Let's implement a basic image button and explain how to use these dynamic classes. I'm just deriving a class from Button and adding an image file name property.
<ImageButton@Button>:
source: None
Image:
source: root.source
pos: root.pos
size: root.size
# let's use the new classes in another rule:
<MainUI>:
BoxLayout:
ImageButton:
source: 'hello.png'
on_press: root.do_something()
ImageButton:
source: 'world.png'
on_press: root.do_something_else()
In Python, you can create an instance of a dynamic class as follows:
from kivy.factory import Factory
button_inst = Factory.ImageButton()
Note Dynamic classes allow a child class to be declared before its parent class. However, this leads to a non-intuitive situation where the parent property / method overrides the child property / method. Be careful if you choose this behavior.
Templates
There are two things you need to do to use Template in Kivy.
The syntax of Template is as follows.
# With only one base class
[ClassName@BaseClass]:
# .. definitions ..
# With more than one base class
[ClassName@BaseClass1,BaseClass2]:
# .. definitions ..
For example, for a list, you need to create an entry with an image on the left and a label on the right. You can create a template to make the definition easier to use. Therefore, create a template that uses two entries in the context. The image file name and title are as follows.
[IconItem@BoxLayout]:
Image:
source: ctx.image
Label:
text: ctx.title
In Python, you can instantiate a template like this:
from kivy.lang import Builder
# create a template with hello world + an image
# the context values should be passed as kwargs to the Builder.template
# function
icon1 = Builder.template('IconItem', title='Hello world',
image='myimage.png')
# create a second template with other information
ctx = {'title': 'Another hello world',
'image': 'myimage2.png'}
icon2 = Builder.template('IconItem', **ctx)
# and use icon1 and icon2 as other widget.
In most cases, you will use a lot of redefinition when creating screens with kv lang. This example creates a toolbar based on BoxLayout and places some Image widgets that respond to the on_touch_down event.
<MyToolbar>:
BoxLayout:
Image:
source: 'data/text.png'
size: self.texture_size
size_hint: None, None
on_touch_down: self.collide_point(*args[1].pos) and root.create_text()
Image:
source: 'data/image.png'
size: self.texture_size
size_hint: None, None
on_touch_down: self.collide_point(*args[1].pos) and root.create_image()
Image:
source: 'data/video.png'
size: self.texture_size
size_hint: None, None
on_touch_down: self.collide_point(*args[1].pos) and root.create_video()
You can see that the size and size_hint attributes are exactly the same. More than that, the on_touch_down callback and image are changing. These are the variable parts of the Template that can be put into context. Let's create an Image Template:
[ToolbarButton@Image]:
# This is the same as before
size: self.texture_size
size_hint: None, None
# Now, we are using the ctx for the variable part of the template
source: 'data/%s.png' % ctx.image
on_touch_down: self.collide_point(*args[1].pos) and ctx.callback()
Templates can be used directly in MyToolbarRule.
<MyToolbar>:
BoxLayout:
ToolbarButton:
image: 'text'
callback: root.create_text
ToolbarButton:
image: 'image'
callback: root.create_image
ToolbarButton:
image: 'video'
callback: root.create_video
That's all.
When creating the context, do the following:
<MyRule>:
Widget:
id: mywidget
value: 'bleh'
Template:
ctxkey: mywidget.value # << fail, this references the id
# mywidget
<MyRule>:
Template:
ctxkey: 'value 1' if root.prop1 else 'value2' # << even if
# root.prop1 is a property, if it changes value, ctxkey
# will not be updated
Template definitions do not support inheritance because they replace the entire similarly named definition.
Sometimes you want to inherit from a widget in order to use Python properties without using the .kv definition styles. For example, you want to inherit from Label, but you can define your own canvas instruction instead of automatically using the canvas instruction inherited from Label. This can be achieved by prepending a dash (-) to the class name in the .kv style definition.
In myapp.py:
class MyWidget(Label):
pass
Then in my.kv:
<-MyWidget>:
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
size: (32, 32)
MyWidget now has Color and Rectangle instructions in the canvas without using the instructions inherited from Label.
As with redefining styles, you may want to keep all KV-defined styles and inherit them from your widget, except for styles applied to certain properties. For example, I want to inherit from Button, but instead of relying on background_normal and background_down values, I can set my own * state_image *. This can be achieved by prepending a dash (-) to the state_image property name in the .kv style definition.
In myapp.py
class MyWidget(Button):
new_background = StringProperty('my_background.png')
And in my.kv
<MyWidget>:
-state_image: self.new_background
MyWidget now has a state_image background set only with new_background, and it is possible that state_image was not set in previous styles.
Note The old Rule has been cleared, but it will be applied during widget creation and will be removed when a new Rule with a dash is reached. This means that you can initially set the property using the old Rule.
Properties can be initialized in KV and Python. For example, in KV
<MyRule@Widget>:
text: 'Hello'
ramp: 45.
order: self.x + 10
MyRule () initializes all three kivy properties to the specified KV value. Apart from Python, if the property already exists as a kivy property, you can use a property such as MyRule (* line ='Bye', side = 55 *).
But what about the final value of the property when MyRule (* text ='Bye', order = 55 *) is executed? The quick rule is that Python initialization is stronger against certain rules than KV initialization.
Specifically, the kwarg given to the python initializer is always applied first. In the example above, the text is set to "Bye" and the order is set to "55". And all KV rules apply, except for constant rules that override the values provided by the Python initializer.
That is, the KVRules that do not create text-like bindings are text:'Hello' and ramp: 45. If the value of that property is provided in Python, that Rule does not apply.
So in the MyRule (* text ='Bye', order = 55 *) example, the text would be "Bye", the ramp would be 45, and the order to create the binding would be set to 55, but KVRuleself.x + 10 It applies to anything.
Directives allow you to add declarative commands such as imports and constant definitions to your lang file. Directives are added as comments in the following format:
#:<directivename> <options>
import
** Added in 1.0.5. **
How to write:
#:import <alias> <package>
You can import the package to be described.
#:import os os
<Rule>:
Button:
text: os.getcwd()
For more complicated writing,
#:import ut kivy.utils
<Rule>:
canvas:
Color:
rgba: ut.get_random_color()
** Added in 1.0.7. **
You can import classes directly from the module.
#: import Animation kivy.animation.Animation
<Rule>:
on_prop: Animation(x=.5).start(self)
set
** Added in 1.0.6. **
How to write
#:set <key> <expr>
Set a key that can be used anywhere in kv. For example:
#:set my_color (.4, .3, .4)
#:set my_color_hl (.5, .4, .5)
<Rule>:
state: 'normal'
canvas:
Color:
rgb: my_color if self.state == 'normal' else my_color_hl
include
grammar:
#:include [force] <file>
Contains external Kivy files. This allows you to split complex widgets into individual files. When include is forced, the file is first unloaded and then reloaded. For example:
# Test.kv
#:include mycomponent.kv
#:include force mybutton.kv
<Rule>:
state: 'normal'
MyButton:
MyComponent:
# mycomponent.kv
#:include mybutton.kv
<MyComponent>:
MyButton:
# mybutton.kv
<MyButton>:
canvas:
Color:
rgb: (1.0, 0.0, 0.0)
Rectangle:
pos: self.pos
size: (self.size[0]/4, self.size[1]/4)
API
class kivy.lang.Observable
Added in 1.9.0
Bases: kivy.event.ObjectWithUid
Observable is a stub class that defines the methods required for binding. EventDispatcher is an example of a class that implements the binding interface. See EventDispatcher for more information.
fbind()
Added in 1.9.0
See EventDispatcher.fbind ().
Note The fbind () method has been added to maintain backward compatibility with derived classes that may have inherited from the Observable. The default implementation of fbind () is to create a partial function to pass to bind while preserving uid and largs / kwargs. However, funbind () (and unbind_uid ()) must first look up this partial function using largs / kwargs or uid and then call unbind () on the returned function, so it's pretty much It is inefficient. For better performance, we recommend overriding these methods with derived classes for direct binding. Similar to EventDispatcher.fbind (), this method returns 0 on failure and a positive unique uid on success. This uid can be used with unbind_uid ().
## funbind()
Added in 1.9.0
fbind()And EventDispatcher.funbind()Please see
## unbind_uid()
Added in 1.9.0
fbind()And EventDispatcher.unbind_uid()Please see.
## class kivy.lang.BuilderBase
Added in 1.0.0
Bases: builtins.object
The builder parses the kv file and creates a Parser to merge the results into internal rules, templates, etc.
By default, the builder is a global Kivy instance used by widgets that can read other kv files in addition to the default one.
## apply(widget, ignored_consts=set())
Added in 1.0.0
Find and apply all the rules that match the widget.
*ignored_consts*Is a set or list type that is a property name to which the widget's constant KV rules (that is, rules that do not create bindings) do not apply. This will, for example, skip constant rules that overwrite values initialized in Python.
## apply_rules(widget, rule_name, ignored_consts=set())
Added in 1.9.2
rule_Find all the rules that match the name widget and*widget*Applies to.
*ignored_consts*Is a set or list type that is a property name to which the widget's constant KV rules (that is, rules that do not create bindings) do not apply. This will, for example, skip constant rules that overwrite values initialized in Python.
## load_file(filename, **kwargs)
Added in 1.0.0
Inserts the file into the language builder and returns the root widget (if defined) for the kv file.
**parameter**:
rulesonly: bool type, default is False.
If True, the Builder will raise an exception if there is a root widget in the definition.
** load_string(string, **kwargs)
Added in 1.0.0
Inserts a string into Language Builder and returns the root widget (if defined) for the kv string.
**parameter**:
rulesonly: bool type, default is False.
If True, the Builder raises an exception if there is a root widget in the definition.
** match(widget) Added in 1.0.0
Added in 1.0.0
Match widget*ParserRule*Returns a list of objects.
** match_rule_name(rule_name)
Added in 1.0.0
Match widget*ParserRule*Returns a list of objects.
** sync()
Added in 1.7.0
Performs all wait operations, including executing all canvas-related expressions.
** template(*args, **ctx)
Added in 1.0.5
Create a special Template with a specific context.
Templates allow you to create custom widgets from kv lang definitions. Check the usage status of Template.
## unbind_property(widget, name)
Added in 1.9.1
Unbinds the handler created by all the widget rules that set the name.
This effectively clears all the rules of the widget that takes the form
**name: rule**
Example:
w = Builder.load_string(''' ... Widget: ... height: self.width / 2. if self.disabled else self.width ... x: self.y + 50 ... ''')
w.size [100, 100]
w.pos [50, 0]
w.width = 500 w.size [500, 500]
Builder.unbind_property(w, 'height') w.width = 222 w.size [222, 500]
w.y = 500 w.pos [550, 500]
** unbind_widget(uid)
Added in 1.7.2
Unbinds all handlers created by the widget's KV rules. Kivy because the builder is using it in the widget destructor.uix.widget.Widget.The uid is passed here instead of the widget itself.
This will effectively clear all KV rules associated with this widget.
An example is as follows.:
w = Builder.load_string(''' ... Widget: ... height: self.width / 2. if self.disabled else self.width ... x: self.y + 50 ... ''')
w.size [100, 100]
w.pos [50, 0]
w.width = 500 w.size [500, 500]
Builder.unbind_widget(w.uid) w.width = 222 w.y = 500 w.size [222, 500]
w.pos [50, 500]
## unload_file(filename)
Unloads all rules associated with previously imported files.
Added in 1.0.8
## Warning
This will not remove any rules or templates that are already applied or used in the current widget. It only affects the creation of the following widgets or calls to templates.
## exception kivy.lang.BuilderException(context, line, message, cause=None)
Added in 1.0.0
Bases: kivy.lang.parser.ParserException
The exception that occurs when the builder fails to apply the rule to the widget.
## class kivy.lang.Parser(**kwargs)
Added in 1.0.0
Bases: builtins.object
Create a Parser object that parses a Kivy Language file or Kivy content.
## parse(content)
Added in 1.0.0
Parses the contents of the Parser file and returns a list of root objects.
## parse_level(level, lines, spaces=0)
Added in 1.0.0
Current level (level*Analyze the indentation of (space).
## strip_comments(lines)
Added in 1.0.0
Delete comments on all lines at once. Comments should be written on a single line, not at the end of the line. The first non-whitespace character in the comment line must be #.
## exception kivy.lang.ParserException(context, line, message, cause=None)
Added in 1.0.0
Bases: Exception
An exception that occurs when something goes wrong with the kv file.