『Python Kivy』Kivy模板语言KV说明
语言概念
KV语言允许你以声明的方式创建控件树,以及绑定控件属性到其他的控件或使用一种自然的方式进行回调。
- 它允许非常快速并灵活的改变你的UI。
- 它还可以让你的应用程序与应用程序的界面进行分隔。
如何加载kv文件
你可以告诉Kivy直接加载一个字符串或一个文件。如果这个字符串或文件定义了一个根控件,它将被下面的方法返回:
Builder.load_file('path/to/file.kv)
或者
Builder.load_string(kv_string)
内容规则
KV源自规则的搭建,这些规则被用于描述一个Widget的内容,你可以有一个根规则,以及一些类或模板规则。
你可以以如下方式声明你的根控件类:
Widget:
使用如下方式声明其他控件:
<MyWidget>:
KV语言有三个特殊的关键字:
- app: 总是与你的应用关联
- root: 与当前控件的根控件关联
- self: 与控件关联
特殊符号
从python中实现一些功能:
#:import name x.y.z
等价于:
from x.y import z as name
设置一个全局值:
#:set name value
等价于:
name = value
示例
MyRootWidget:
BoxLayout:
Button:
Button:
等价于:
root = MyRootWidget()
box = BoxLayout()
box.add_widget(Button())
box.add_widget(Button())
root.add_widget(box)
赋值:
GridLayout:
cols: 3
等价于:
grid = GridLayout(cols=3)
以及
GridLayout:
cols: len(root.data)
等价于:
grid = GridLayout(cols=len(self.data))
self.bind(data=grid.setter('cols'))
事件绑定
Widget:
on_size: my_callback()
你可以使用args关键字来传送值:
TextInput:
on_text: app.search(args[1])
更复杂的表达式:
pos: self.center_x - self.texture_size[0] / 2., self.center_y - self.texture_size[1] / 2.
这个表达式监听center_x
与center_y
以及texture_size
的变化。如果它们变化了,表达式会重新计算并更新pos
字段。
你也可以处理on_
事件在你的kv语言中。例如TextInput
类有一个焦点属性,这个属性可以使用如下的方式访问:
TextInput:
on_focus: print(args)
扩展画板
KV语言可以用于定义你的控件的画板结构:
MyWidget:
canvas:
Color:
rgba: 1, .3, .8, .5
Line:
points: zip(self.data.x, self.data.y)
并且当属性值改变化,它们进行更新:
当然,你也可以使用 canvas.before
和 canvas.after
.
引用其他控件
在一个控件树中,经常需要访问/引用别的控件。KV语言提供一种方式来实现,使用id
。将他们当成一个类级别变量,这仅能够用于KV语言中。考虑下面的示例:
<MyFirstWidget>:
Button:
id: f_but
TextInput:
text: f_but.state
<MySecondWidget>:
Button:
id: s_but
TextInput:
text: s_but.state
id
被限制在它被定义的范围内,所以在上面的代码中s_but
不能被上面的<MySecondWidget>
访问。
一个id
是一个到控件的弱引用并不是这个控件本身。正因如此,存储id
对于在垃圾回收中保持控件是不够的。如:
<MyWidget>
label_widget: label_widget
Button:
text: 'Add Button'
on_press: root.add_widget(label_widget)
Button:
text: 'Remove Button'
on_press: root.remove_widget(lable_widget)
Label:
id: label_widget
text: 'widget'
虽然一个关联到label_widget
存储在MyWidget
中,但是当另外的引用已经被使用后,还不足以保持这个对象的存活,因为它仅仅是一个弱引用。
因此,在移除按钮被点击后,窗口被重新调整尺寸,当添加按钮被点击以添加控件,一个ReferenceError
将会产生:弱引用对象不存在将被抛出。
为了保持控件存活,一个到label_widget
的直接引用必须被保持。在这个例子中,使用id.__self__
或label_widget.__self__
来达到这一效果。正确的方法是:
<MyWidget>
label_widget: label_widget.__self__
在你的Python代码中,访问已经被定义在KV语言中的控件
KV示例:
<MyFirstWidget>:
# both these variables can be the same name and this doesn’t lead to
# an issue with uniqueness as the id is only accessible in kv.
txt_inpt: txt_inpt
Button:
id: f_but
TextInput:
id: txt_inpt
text: f_but.state
on_text: root.check_status(f_but)
在python代码中调用:
# ...
class MyFirstWidget(BoxLayout):
txt_inpt = ObjectPropery(None)
def check_status(self, btn):
print('button state is : {state}'.format(state=btn.state))
print('text input text is :{txt}'.format(txt=self.txt_input))
或者在KV中:
<Marvel>
Label:
id: loki
text: 'loki: I AM YOUR GOD!'
Button:
id: hulk
text: "press to smash loki"
on_release: root.hulk_smash()
在Python中:
当你的KV文件已经被解析,Kivy使用ids
收集所有的控件标签,并且将放在self.ids
字典中。这意味着你也可以遍历这个控件并访问他们。
class Marvel(BoxLayout):
def hulk_smash(self):
self.ids.hulk.text = "hulk: puny god!"
self.ids.loki.text = "loki: >_<!!!"
# ...
for key, val in self.ids.items():
print("key={0}, val={1}".format(key, val))
动态类
<MyWidget>:
Button:
text: "Hello world, watch this text wrap inside the button"
text_size: self.size
font_size: ’25sp’
markup: True
Button:
text: "Even absolute is relative to itself"
text_size: self.size
font_size: ’25sp’
markup: True
Button:
text: "Repeating the same thing over and over in a comp = fail" text_size: self.size
font_size: ’25sp’
markup: True
Button:
代替为每一个按钮的属性重复设置同样的值,我们可以仅仅使用一个__模板__,如下所示:
<MyBigButt@Button>:
text_size: self.size
font_size: ’25sp’
markup: True
<MyWidget>:
MyBigButt:
text: "Hello world, watch this text wrap inside the button"
MyBigButt:
text: "Even absolute is relative to itself"
MyBigButt:
text: "repeating the same thing over and over in a comp = fail"
MyBigButt:
这个类仅仅被这条规则的声明所创建,从Button
类继承并在没有在Python代码中添加新的代码的情况下,允许我们改变默认的值并为所有它的实例创建绑定。
在多个控件中重复使用样式
my.kv文件:
<MyFirstWidget>:
Button:
on_press: self.text(txt_inpt.text)
TextInput:
id: txt_inpt
<MySecondWidget>:
Button:
on_press: self.text(txt_inpt.text)
TextInput:
id: txt_inpt
myapp.py文件:
class MyFirstWidget(BoxLayout):
def text(self, val):
print(’text input text is: {txt}’.format(txt=val))
class MySecondWidget(BoxLayout):
writing = StringProperty(’’)
def text(self, val):
self.writing = val
因为所有类共享同样的.kv
样式,如果我们为所有的控件复用样式,这个设计能够被简化。你可以在.kv
中像下面这样实现:
<MyFirstWidget,MySecondWidget>:
Button:
on_press: self.text(txt_inpt.text)
TextInput:
id: txt_inpt
通过使用一个逗号来分隔类名,所有的在声明中列出的类将拥有同样的属性。
使用Kivy语言进行设计
在py文件中
import kivy
kivy.require(’1.8.0’)
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
class Controller(FloatLayout):
’’’Create a controller that receives a custom widget from the kv lang file.
Add an action to be called from the kv lang file. ’’’
label_wid = ObjectProperty()
info = StringProperty()
def do_action(self):
self.label_wid.text = ’My label after button press’
self.info = ’New info text’
class ControllerApp(App):
def build(self):
return Controller(info=’Hello world’)
if __name__ == ’__main__’:
ControllerApp().run()
controller.kv中进行设计
#:kivy 1.8.0
<Controller>:
label_wid: my_custom_label
BoxLayout:
orientation: ’vertical’
padding: 20
Button:
text: ’My controller info is: ’ + root.info
on_press: root.do_action()
Label:
id: my_custom_label
text: ’My label before button press’
『Python Kivy』Kivy模板语言KV说明的更多相关文章
- 『Python进阶』专题汇总
基础知识 Python3内置函数 『Python』库安装 『流畅的Python』第1~4章_数据结构.编码 『Python』基础数据结构常见使用方法 『Python CoolBook』数据结构和算法_ ...
- 『Python CoolBook』Cython
github地址 使用Cython导入库的话,需要一下几个文件: .c:C函数源码 .h:C函数头 .pxd:Cython函数头 .pyx:包装函数 setup.py:python 本节示例.c和.h ...
- 6月15日 python学习总结 Django模板语言相关内容
Django模板语言相关内容 Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} ...
- Python Django 之 Template 模板语言简介
一.什么事模板语言 html+逻辑控制语句 二.模板语言的作用 帮助前端处理后端发来的数据,方便前端展示(杂糅渲染) 三.模板语言语法 1.{{变量}} 变量使用双大括号{{}} 2.万能的句点号. ...
- 『Python CoolBook』C扩展库_其六_从C语言中调用Python代码
点击进入项目 一.C语言运行pyfun的PyObject对象 思路是在C语言中提供实参,传给python函数: 获取py函数对象(PyObject),函数参数(C类型) 获取GIL(PyGILStat ...
- 『Python CoolBook』C扩展库_其五_C语言层面Python库之间调用API
点击进入项目 一.C层面模块添加API 我们仍然操作如下结构体, #include <math.h> typedef struct Point { double x,y; } Point; ...
- 『Python CoolBook』使用ctypes访问C代码_下_demo进阶
点击进入项目 这一次我们尝试一下略微复杂的c程序. 一.C程序 头文件: #ifndef __SAMPLE_H__ #define __SAMPLE_H__ #include <math.h&g ...
- 『Python CoolBook』C扩展库_其四_结构体操作与Capsule
点击进入项目 一.Python生成C语言结构体 C语言中的结构体传给Python时会被封装为胶囊(Capsule), 我们想要一个如下结构体进行运算,则需要Python传入x.y两个浮点数, type ...
- 『Python CoolBook』Cython_高效数组操作
数组运算加速是至关科学计算重要的领域,本节我们以一个简单函数为例,使用C语言为python数组加速. 一.Cython 本函数为一维数组修剪最大最小值 version1 @cython.boundsc ...
随机推荐
- BZOJ3940:[USACO]Censoring(AC自动机,栈)
Description Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so ...
- mxnet导入图像数据
图像的标签在一个json文件中. %matplotlib inline import json import gluonbook as gb import mxnet as mx from mxnet ...
- 【[JLOI2013]卡牌游戏】
思路太妙了 刚开始yy出了一种比较自然的dp方法,就是按照游戏的进行来开始dp,设\(dp[i][j]\)表示第\(i\)个人为庄家,还剩下\(j\)个人的概率为多少,但是很快发现这个样子没法转移,因 ...
- Eclipse安装Sonarlint插件
这里安装的是Sonarlint3.6.插件安装非常简单.插件比Sonar更为简单快捷. 一.首先通过点击Eclipse上方Help菜单会出现一个下拉列表,点击其中的Eclipse MarketPlac ...
- PAT——1002. 写出这个数
读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式:在一行内输出n的各位数字之和的每 ...
- POJ 1753 Flip Game (状态压缩 bfs+位运算)
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...
- Vue教程:计算属性computed与侦听器watch(三)
计算属性computed 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="example" ...
- Oracle中order by case 用法
select * from ly_familyinformation ' ' order by case when relation = '购房人/申请人' then when relation = ...
- 严重: A child container failed during start java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component
自己写了个最简单的springMVC项目练练手,没有用maven,在WebContent中新建了lib文件夹,将jar包复制到这里面,然后add to build path到项目里. 启动Tomcat ...
- Jquery中on绑定事件 点击一次 执行多次 的解决办法
举个例子,在同一个页面有下拉选择框 <select class="mySelect"> <option value="user">按用户 ...