Kivy使用篇10

Kivy使用篇之倒计时小程序

  1. canvas canvas.before canvas.after 的区别
  2. InstructionGroup 使用
  3. TextInput设置为单行数值输入框
  4. FloatLayout 布局使用

自定义按钮
使用canvas绘图来自定义一个圆形按钮,作为控制按钮
在背景中绘制一个圆形,并设置backgroud_color为透明,代码如下:

:
    # 背景
    canvas.before: 
        Color:
            rgb:(1, 0, 0)
        Ellipse:
            size: (min(self.width, self.height), min(self.width, self.height))
            pos: (self.center_x - min(self.width, self.height) / 2, self.center_y - min(self.width, self.height) / 2)
    background_color: (0, 0, 0, 0)  # 设置背景透明

绑定按钮的state, 用来处理on_press事件时的颜色改变,代码如下:

class EllipticButton(Button):
    """椭圆按钮类"""
    def __init__(self, **kwargs):
        super(EllipticButton, self).__init__(**kwargs)
        self.bind(state=self.change_foreground_color)

    def change_foreground_color(self, s, state):
        """修改前景色"""
        front_color = Color(0, 1, 0, .8)  # 修改此处可更改前景色
        front = InstructionGroup()
        front.add(front_color)
        front.add(Rectangle(pos=self.pos, size=self.size))
        if state == 'normal':
            self.canvas.after.clear()
        else:
            self.canvas.after.add(front)

当按钮按下时,前景色为绿色 80%透明度
数字输入框
自定义一个数字输入框,仅允许输入规定范围的数字数值。
初始化函数如下:

    def __init__(self, **kwargs):
        super(NumericTextInput, self).__init__(**kwargs)
        self.halign = 'center'  # 文本居中
        self.multiline = False  # 单行
        self.size_hint_y = None  # 高度为绝对值
        # self.height = self.line_height
        self.input_filter = 'int'  # 仅可输入数值
        self.bind(text=self.on_text)
        self.bind(value=self.on_value)

其中valueNumericProperty,用来指示输入框文本代表的数值,另外,定义一个属性值_max,用来规定输入框允许输入的最大值,代码如下:

    _max = NumericProperty(0)  # 可现实最大数值
    value = NumericProperty(0)  # 数值

当文本改变时,处理程序如下:

    def on_text(self, sender, txt):
        """文本值改变事件"""
        if txt == '':
            self.text = '00'
        else:
            self.value = int(txt)
            if self.value >= self._max:  # 当值大于超过最大值时,设置值为0
                self.text = "{:0>2d}".format(0)
                self.select_all()
            else:  # 格式化显示样式
                self.text = "{:0>2d}".format(self.value)

当数值改变时,处理程序如下:


    def on_value(self, sender, v):
        """修改文本"""
        self.text = "{:0>2d}".format(self.value)

倒计时程序
倒计时工作流程

  1. 设置目标数值
  2. 启动内部计数器
  3. 当内部计数器计数值达到目标值时,停止计数器
    处理线程如下:
    def thread_counting(self):
        """倒计时线程"""
        start = time.time()
        while self.is_run:
            if self.is_paused:
                self.stop_time = time.time() - start - self.timer
            else:
                self.timer = time.time() - start - self.stop_time
            if self.timer >= self.counter:  # 停止计数
                self.is_run = False
            time.sleep(.01)

timerNumericProperty,当值改变时,自动刷新倒计时设置器的值,即:

    def update_timer(self, s, t):
        """更新倒数器"""
        remain = int(self.counter - t)  # 剩余倒计时值
        self.t_hour.value = remain // 3600
        self.t_min.value = (remain // 60) % 60
        self.t_sec.value = remain % 60
        self.ids.label_timer.text = "{:0>2d}".format(99 - int(t * 100) % 100)

FloatLayout布局
倒计时设置器布局在一个FloatLayout中,部分示例如下:

	FloatLayout:
        size_hint: (1, .8)
        BoxLayout:
            size_hint: (.5, None)
            height: lb.texture_size[1]  # 设置高度为标签文本高度
            pos_hint: {'x': .25, 'y': .5}
            # 倒计时小时值手动输入框
            NumericTextInput:
                id: carousel_hour
                _max: 100
                font_size: 100
                height: lb.texture_size[1]
            Label:
                id: lb
                text: ':'
                font_size: 100
                size: self.texture_size

其中size_hint: (.5, None)的设置,可将FloatLayout中的BoxLayout的宽度设置为50%,高度设置为绝对值,height: lb.texture_size[1]设置BoxLayout的高度值。pos_hint: {'x': .25, 'y': .5}
设置其位置相对值。

        # 控制按钮-设置倒计时小时值
        Button:
            text: '+'
            size_hint: (None, None)
            size: carousel_hour.size
            pos: carousel_hour.pos[0], carousel_hour.pos[1] + carousel_hour.height
            on_press: carousel_hour.value = (carousel_hour.value + 1) % carousel_hour._max
        Button:
            text: '-'
            size_hint: (None, None)
            size: carousel_hour.size
            pos: carousel_hour.pos[0], carousel_hour.pos[1] - carousel_hour.height
            on_press: carousel_hour.value = (carousel_hour.value - 1) % carousel_hour._max

FloatLayout中添加按钮,按钮位置相对于其设置的倒计时输入框而改变。
运行示例如下:
Kivy使用篇10_第1张图片
手机运行示例:
Kivy使用篇10_第2张图片
源码地址:https://github.com/babylco0/python3_examples/tree/master/count

你可能感兴趣的:(kivy)