How to use Python Kivy (reference) -I translated Kivy Language of API reference-

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.

Overview

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.

Syntax of a kv File

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.

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.

Expression values, on_property, ids and reserved keywords (Value Expressions, on_property Expressions, ids and Reserved Keywords)

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.

Valid expressons

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')

Relationship Between Values and Properties

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

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

Syntax of templates

There are two things you need to do to use Template in Kivy.

  1. The context to pass for the context (which will be ctx in the Template).
  2. Template kv definition.

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.

Template example (Template example)

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.

Template limitations

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.

Redefining a widget ’s style

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.

Redefining a widget ’s property style

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.

Order of kwargs and KV rule application

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.

Language Directives

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.




Recommended Posts

How to use Python Kivy (reference) -I translated Kivy Language of API reference-
How to use Python Kivy ① ~ Basics of Kv Language ~
I tried to summarize how to use matplotlib of python
How to use OpenPose's Python API
[Python] How to use Typetalk API
[Python] Summary of how to use pandas
[Python2.7] Summary of how to use unittest
Summary of how to use Python list
[Python2.7] Summary of how to use subprocess
[Question] How to use plot_surface of python
[Python] How to use two types of type ()
How to use Python Kivy ④ ~ Execution on Android ~
Summary of how to use MNIST in Python
[Python] How to use list 2 Reference of list value, number of elements, maximum value, minimum value
[BigQuery] How to use BigQuery API for Python -Table creation-
[Python] How to use list 1
How to use Python argparse
Python: How to use pydub
[Python] How to use checkio
I tried to summarize how to use pandas in python
[Python] How to use input ()
How to use Python lambda
[Python] How to use virtualenv
python3: How to use bottle (3)
python3: How to use bottle
How to use Python bytes
[Python] Summary of how to use split and join functions
Comparison of how to use higher-order functions in Python 2 and 3
I didn't know how to use the [python] for statement
Python: How to use async with
Summary of how to use pandas.DataFrame.loc
How to use Requests (Python Library)
How to use SQLite in Python
Summary of how to use pyenv-virtualenv
How to use computer language slowly 2
[Python] How to use list 3 Added
How to use Mysql in python
How to use ChemSpider in Python
How to use FTP with Python
Python: How to use pydub (playback)
How to use PubChem in Python
How to use bing search api
How to use python zip function
How to use computer language slowly
Summary of how to use csvkit
Sample to use after OAuth authentication of BOX API with Python
Basic grammar of Python3 system (how to use functions, closures, lambda functions)
I want to use both key and value of Python iterator
Python> Comprehension> cells> I was taught how to use double comprehension / itertools
[Introduction to Python] How to use class in Python?
[Kivy] How to install Kivy on Windows [Python]
[python] How to use __command__, function explanation
I want to use jar from python
[Python] How to use import sys sys.argv
[Python] Organizing how to use for statements
Memorandum on how to use gremlin python
python: How to use locals () and globals ()
How to use __slots__ in Python class
Jupyter Notebook Basics of how to use
How to use "deque" for Python data
Basics of PyTorch (1) -How to use Tensor-