Kivy模板语言KV说明
来源:互联网 发布:流星网络电视在线直播 编辑:程序博客网 时间:2024/04/28 18:15
语言概念
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 FloatLayoutfrom kivy.app import Appfrom kivy.properties import ObjectProperty, StringPropertyclass 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’
- Kivy模板语言KV说明
- kivy 中 .kv 文件的使用
- 翻译:kivy语言
- 模板语言基本说明
- Velocity模板语言(VTL):说明
- c语言编程文件和函数说明模板
- 模板说明
- 浅尝Kivy
- kivy reference
- 什么是Kivy???
- kivy安装
- KIVY安装
- kivy踩坑记
- DFS & KV
- KV-MemNN
- rup 模板说明
- Nettiers模板属性说明
- Nettiers模板属性说明
- 沟通两海 —— 海峡
- CodeForces-493A.Vasya and Football
- 简单C++输出
- SparseArray到底哪点比HashMap好
- HDU 2546 饭卡(简单01背包)
- Kivy模板语言KV说明
- iOS & XML浅谈
- 数据结构学习四 队列
- 2016 Personal Training #3 Div.2 SGU 409
- SD/MMC 内部寄存器
- Qt5.6_qml_发布qml程序
- web框架学习前复习——filter
- Android MVP 模式 详解
- UVALive 7272 Promotions【拓扑排序】【bitset】