部分UX部件

前面我们已经对Layout布局,以及Canvas 画布进行了学习,我们接下来来看看,经常使用的一些部件,这些部件是图形界面设计的重要组成部分,合理使用可以更高效的开发程序。我们先从简单部件开始。

Button

button常用属性

属性说明
background_color按钮的背景颜色,rgba格式,默认为灰色
text按钮显示的文本
font_size文本字体的大小,默认为15sp
color文本字体颜色,rgba格式,默认为白色[1,1,1,1]
state按钮状态,默认为“normal”,可设置成“down”
disables如果为True时则禁用按钮,默认为False
background_disabled_normal默认为“kivytoolsthemingdefaultthemebutton_disabled_pressed.png”
background_disabled_down默认为“kivytoolsthemingdefaultthemebutton_disabled.png”
background_down按下按钮时显示的图形,默认为“kivytoolsthemingdefaultthemebutton_pressed.png”
background_normal未按下按钮时显示的图像,默认为“kivytoolsthemingdefaultthemebutton.png"
border与background_normal 和background_down 属性一起使用,可用于自定义背景。
触发事件
  • on_press:按下按钮触发该事件
  • on_release: 按下按钮并释放时,触发该事件

Label标签

Kivy中的Label小部件用于显示文本,目前只支持ASCII和Unicode编码字符(暂不支持中文),可以通过属性设置文本内容,字体,大小,颜色,对齐方式,换行以及标记文字等内容。

常用属性
属性说明
text标签显示文本大小,默认为空字符串
text_size标签文本大小、默认为(None,None),表示无限制
font_name要使用字体的文件名,可以是绝对路径或者resource_find解析的相对路径
font_size文本字体的大小,以像素为单位,默认为15sp
bold字体使用粗体,默认为False
italic字体使用斜体,默认为False
color字体颜色,格式为rgba,默认为白色[1,1,1,1]
halign文本的水平对齐方式,默认为‘auto’,可选参数为: buttom,middle 或者 Center 和 top
markup是否分割所有标记文本,默认为False
refs使用[ref=xxx]xxx[/ref]标记部分文本,使用时需要将markup属性设置为True
underline文本上添加下划线,默认为False
padding_x小部件框内文本的水平填充,默认为0
padding_y小部件框内文本的垂直填充,默认为0
padding以(padding_x,padding_y)格式填充文字
texture文本的纹理对象,属性更改时会自动呈现文本,默认为None
texture_size文本纹理大小,由字体大小和文本确定
unicode_error如何处理Unicode解码错误,可选参数为:“strict”, "replace"(默认)和“ignore”
strikethrough在文本中添加删除线
strip与python 内置函数一致,是否删除空格以及换行符,默认为False
outline_color文本轮廓颜色,格式为rgba, 默认为[0,0,0]
outline_width文本周围轮廓的宽度,单位为像素,默认为None表示不会渲染轮廓
max_lines要使用的最大行数,默认为0,表示无限制
shorten是否应该尽可能缩短文本内容,默认为False
shorten_from在哪一侧缩短文本,默认为center,可选 left,right 和 center
split_str当shorten 为True 时,差分字符串,默认为空字符串
is_shortened是否以缩短事件的方式进行渲染,默认为False
line_height文本的行高,默认为1.0
base_direction文本基本方向,当halign为auto 时,会影响水平对齐,可设置参数为:None、ltr (从左到右)、rtl、weak_lte、weak_rtl
disabled_color禁用小部件时文本轮廓的颜色,格式为rgb,默认为[0,0,0]
ellipsis_options使用'···'缩短文本,使用时要设置markuo和shorten为True,默认为空字典{}
font_blended使用混合字体,默认为True
font_context字体上下文,默认为None表示该字体单独使用
font_family字体系列,仅在使用font_context时使用,
font_features将CSS格式的OpenType字体传给Pango ,默认为空字符。
font_hinting渲染字体的提示选项,可选参数为’normal‘,'light','mono'和None
font_kerning是否为字形渲染,启用字距调整,默认为True
mipmap是否将OpenGL mipmapping应用于纹理,默认为False

开启以下需要将markup打开

可用标记解释可用标记解释
b加粗i斜体
u下划线s删除线
sub下标sup上标
font=更改字体size=]大小
color=#颜色[anchor=]锚点,(x,y)
ref=添加一个交互式引用区,引用一个方法text_language=<>文本语言,例: “<zh_CN>”
&bl[&br]
&&
#:import C kivy.utils.get_color_from_hex

<LabelBoxLayout>:
    orientation: 'vertical'
    Button:
        text: 'Button'
        on_press: root.on_press_btn()
        on_release: root.on_release_btn()

    Label:
        id: lable_btn
        text: 'The first step is one of awareness. It will be hard to make a change to positive thinking without being acutely intimate with the thoughts that run through your mind. Recently, I was amazed to discover deep buried emotions from negative thoughts that I had for fewer than 10 minutes. Without awareness, I would have carried the hurt and anger inside. Awareness helped me to bring them out to the open for me to deal with.'
        font_size: '20sp'
        color: C('#B0C4DE')
        italic: True
        text_size: cm(15), mm(200)
        halign: 'right'
        valign: 'middle'
        strikethrough: True
    Label:
        canvas.before:
            Color:
                rgba: C('#DCDCDC')
            Rectangle:
                pos: self.pos
                size: self.size
        text: 'There are moments in life when [i]you miss someone [color=#"4169E1"]so much that you just want[/color] to pick them from your[/i] dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do.'
        color: C('#FF0000')
        font_size: '15sp'
        bold: True
        text_size: cm(10), mm(100)
        halign: 'center'
        valign: 'middle'
        underline: True
        line_height: 1.0
        markup: True
# !/usr/bin/env python3
# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout


class LabelBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(LabelBoxLayout, self).__init__(**kwargs)

    def on_press_btn(self):
        self.children[1].strikethrough = not self.children[1].strikethrough

    def on_release_btn(self):
        self.children[1].strikethrough = not self.children[1].strikethrough


class LabelBoxApp(App):
    def build(self):
        return LabelBoxLayout()


if __name__ == '__main__':
    LabelBoxApp().run()
触发事件

Kivy中是使用ref 来标记触发事件的,点击ref包裹的文本,就可以触发“on_ref_press”事件。

设置Label 标签的触发事件

在使用ref之前,需要将markup设置为True

# !/usr/bin/env python3
# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.utils import get_color_from_hex


class LabelBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(LabelBoxLayout, self).__init__(**kwargs)
        strtext = 'Awareness [color=#00FF00][ref=label][i]helped me[/i][/ref][/color] to [b]bring[/b] [s]them out[/s] to the open for me to deal with.'
        label_ref = Label(font_size='25sp',text=strtext, markup=True,
                          color=get_color_from_hex('#F0F8FF'))
        label_ref.bind(on_ref_press=self.on_press_btn_label_ref)
        self.add_widget(label_ref)

    def on_press_btn(self):
        self.children[1].strikethrough = not self.children[1].strikethrough

    def on_release_btn(self):
        self.children[1].strikethrough = not self.children[1].strikethrough

    def on_press_btn_label_ref(self, *args):
        self.children[0].strikethrough = not self.children[0].strikethrough


class LabelBoxApp(App):
    def build(self):
        return LabelBoxLayout()


if __name__ == '__main__':
    LabelBoxApp().run()
#:import C kivy.utils.get_color_from_hex

<LabelBoxLayout>:
    orientation: 'vertical'
    Button:
        text: 'Button'
        on_press: root.on_press_btn()
        on_release: root.on_release_btn()

    Label:
        id: lable_btn
        text: 'The [ref=lable]first step[/ref] is one of awareness. It will be hard to make a change to positive thinking without being acutely intimate with the thoughts that run through your mind. Recently, I was amazed to discover deep buried emotions from negative thoughts that I had for fewer than 10 minutes. Without awareness, I would have carried the hurt and anger inside. Awareness helped me to bring them out to the open for me to deal with.'
        font_size: '20sp'
        color: C('#B0C4DE')
        italic: True
        text_size: cm(15), mm(200)
        halign: 'right'
        valign: 'middle'
        on_ref_press:
            print('Click on_ref_press')
            root.on_release_btn()
        strikethrough: True
        markup: True
    Label:
        canvas.before:
            Color:
                rgba: C('#DCDCDC')
            Rectangle:
                pos: self.pos
                size: self.size
        text: 'There are moments in life when [i]you miss someone [color=#"4169E1"]so much that you just want[/color] to pick them from your[/i] dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do.'
        color: C('#FF0000')
        font_size: '15sp'
        bold: True
        text_size: cm(10), mm(100)
        halign: 'center'
        valign: 'middle'
        underline: True
        line_height: 1.0
        markup: True

单位介绍

px、dp和sp,这三个单位的区别在于,它们的定义各不相同:

  • px:指像素,是指基本原色素及其灰度的基本编码,是Pixel的缩写。像素是指基本原色素及其灰度的基本编码,由 Picture(图像)和 Element(元素)这两个单词的字母所组成的。当图片尺寸以像素为单位时,需要指定其固定的分辨率,才能将图片尺寸与现实中的实际尺寸相转换。
    例如:大多数网页制作常用图片分辨率为72,即每英寸像素为72,1英寸等于2.54厘米。
  • dp:安卓开发时的长度单位,Density-independent pixel,是安卓开发用的长度单位,1dp表示在屏幕像素点密度为160ppi时1px长度。。
  • sp:与缩放无关的抽象像素,是字体单位.scale-independent pixel,安卓开发用的字体大小单位。一般情况下可认为sp=dp。

Image图片

使用Image控件来显示图片,可以通过size和pos来设置属性和设置大小和位置,通过source属性来指定图片的相对路径,此外,如果图片大小过大的时候,为了防止卡顿,可以使用异步的方式加载,这我们前面在学习的时候,咱们有试过,使用异步加载图片。

我们先来看看Image有哪些属性。

属性
属性属性
source图片的文件名和路径
texture图像的纹理对象,默认为None
color图像颜色,格式为rgba,默认为[1,1,1,1]
texture_size图像的纹理大小
allow_stretch是否放打图像到边框,默认为False
anim_delay动画延迟,默认为0.25秒 (4fps),若设置为-1,则停止
anim_loop循环播放的次数,默认为0
image_ratio图片比例
keep_data是否存储原始图像数据,经常用在基于像素的碰撞检测,默认为False
keep_ratio是否以忽略图像纵横比的 方式放大图像以适合图像框,默认为True
mipmap是否要将OpenGL mipmapping 应用于纹理,默认为False
nocache是否不将图像添加到内部缓存种,默认为False 表示添加到缓存中
norm_image_size以保留比例的方式标准化图像大小,只读属性,不可更改
reload()重新加载图像
# !/usr/bin/env python3
# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout


class ImageBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(ImageBoxLayout, self).__init__(**kwargs)


class ImageBoxApp(App):
    def build(self):
        return ImageBoxLayout()


if __name__ == '__main__':
    ImageBoxApp().run()

<ImageBoxLayout>:
    canvas:
        Color:
            rgba:[1,1,1,1]
        Rectangle:
            size:self.width+20, self.height+20
            pos: self.x-10,self.y-10
            source:'UxParts.jpg'

    AsyncImage:
        source:'https://blogcdn.sea-whales.cn/blog/typecho/17.jpg'
        size_hint_y: None
        width: 300
        allow_stretch: True   # 自适应
    
    Image:
        source:'https://blogcdn.sea-whales.cn/blog/typecho/17.jpg'
        size_hint_y: None
        width: 300
        allow_stretch: True