Kivy-FloatLayout中的计时器集成

时间:2018-09-22 20:13:28

标签: python layout timer kivy kivy-language

问题很简单,让Kivy将Timer1代码集成为 FloatLayout 中的标签。

我有这个.py文件:

import kivy

kivy.require('1.10.0')

from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.stacklayout import StackLayout
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from digitalclock import DigitalClock
from kivy.animation import Animation

import time


class IntroScreen(Screen):
    pass


class ContScreen(Screen):
    pass


class ScreenManagement(ScreenManager):
    pass


backbone = Builder.load_file("main.kv")


class Status(FloatLayout):
    _change = StringProperty()
    _tnd = ObjectProperty(None)

    def update(self, *args):
        self.time = time.asctime()
        self._change = str(self.time)
        self._tnd.text = str(self.time)
        print (self._change)


class Timer1(Label):
    a = NumericProperty(10)  # seconds
    color = 1, 1, 1, 1
    font_size = 50

    def start(self):
        Animation.cancel_all(self)  # stop any current animations
        self.anim = Animation(a=0, duration=self.a)

        def finish_callback(animation, incr_crude_clock):
            incr_crude_clock.text = "COOL"
        self.anim.bind(on_complete=finish_callback)
        self.anim.start(self)

    def on_a(self, instance, value):
        self.text = str(round(value, 1))


class XGApp(App):
    time = StringProperty()

    def update(self, *args):
        self.time = str(time.asctime())

    def build (self):
        Clock.schedule_interval(self.update, 1)
        t1 = Timer1()
        return backbone


xApp = XGApp()

if __name__ == "__main__":
    xApp.run()

和.kv:

<ContScreen>:
    DigitalClock:
        pos_hint: {'center_x': 0.1, 'center_y': 0.9}
        size_hint: (0.075, 0.075)

    StackLayout
        orientation: "tb-rl"
        spacing: 15

        Button:
            text: "1"
            size_hint: None, .16
            width: 225
            on_press:
                self.background_color = (1.7, 0, 1.7, 1)
                t1.start()

我正在尝试将Timer1方面作为.kv上 FloatLayout 中的标签获取,该按钮在触发按钮时出现。此刻,我得到的是Timer1作为全屏标签。

请帮助!

2 个答案:

答案 0 :(得分:0)

使其工作的一种方法是让Button创建计时器。首先向start_timer()类添加ContScreen方法:

class ContScreen(Screen):
    def start_timer(self, *args):
        timer = Timer1(size_hint=(0.2, 0.2))
        self.add_widget(timer)
        timer.start()

要执行此操作,请进行其他三个更改:

  1. 更改您的main.kv文件以制作一个根小部件(消除<>周围的ContScreen)。
  2. 通过将on_press替换为.kv,来更改t1.start()文件中按钮的root.start_timer()
  3. t1 = Timer1()类的build方法中删除XGApp语句。

另一种方法是在Timer1文件中创建.kv,并在按下Button时使其开始运行。为此,请将您的.kv文件更改为包含Timer

ContScreen:
    DigitalClock:
        pos_hint: {'center_x': 0.1, 'center_y': 0.9}
        size_hint: (0.075, 0.075)

    StackLayout
        orientation: "tb-rl"
        spacing: 15

        Button:
            text: "1"
            size_hint: None, .16
            width: 225
            on_press:
                self.background_color = (1.7, 0, 1.7, 1)
                timer.start()

        Timer1:
            id: timer
            text: '0.0'
            size_hint: (0.2, 0.2)

backbone = Builder.load_file("main.kv")类的定义移至Timer1之后。并将ContScreen类更改回:

class ContScreen(Screen):
    pass

答案 1 :(得分:0)

解决方案

  1. 将“计时器标签”的设计视图从Python代码移到kv文件中。
  2. class Timer 添加构造函数并接受参数root, instance, duration, bg_colour
  3. 在kv文件中,实例化 Timer
  4. 时,传递参数 root(屏幕'cont'),按钮实例,持续时间,背景色
  5. build 方法中,删除t1 = Timer1()

示例

main.py

import kivy

kivy.require('1.11.0')

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from kivy.animation import Animation

import time


class IntroScreen(Screen):
    pass


class ContScreen(Screen):
    pass


class ScreenManagement(ScreenManager):
    pass


class Status(FloatLayout):
    _change = StringProperty()
    _tnd = ObjectProperty(None)

    def update(self, *args):
        self.time = time.asctime()
        self._change = str(self.time)
        self._tnd.text = str(self.time)
        print (self._change)


class Timer(Label):
    a = NumericProperty()  # seconds

    def __init__(self, root, instance, duration, bg_colour, **kwargs):
        super(Timer, self).__init__(**kwargs)
        self.obj = instance
        self.a = duration
        self.root = root

        self.obj.disabled = True    # disable widget/button
        self.obj.background_color = bg_colour
        self.root.add_widget(self)  # add Timer/Label widget to screen, 'cont'

    def animation_complete(self, animation, widget):
        self.root.remove_widget(widget)  # remove Timer/Label widget to screen, 'cont'
        self.obj.background_color = [1, 1, 1, 1]    # reset to default colour
        self.obj.disabled = False   # enable widget/button

    def start(self):
        Animation.cancel_all(self)  # stop any current animations
        self.anim = Animation(a=0, duration=self.a)
        self.anim.bind(on_complete=self.animation_complete)
        self.anim.start(self)

    def on_a(self, instance, value):
        self.text = str(round(value, 1))


class XGApp(App):
    time = StringProperty()

    def update(self, *args):
        self.time = str(time.asctime())

    def build (self):
        Clock.schedule_interval(self.update, 1)
        return Builder.load_file("main.kv")


if __name__ == "__main__":
    XGApp().run()

kv文件

#:import DigitalClock digitalclock
#:import Timer main.Timer

<ContScreen>:
    DigitalClock:
        pos_hint: {'center_x': 0.1, 'center_y': 0.9}
        size_hint: (0.075, 0.075)

    StackLayout
        orientation: "tb-rl"
        spacing: 15

        Button:
            text: "1"
            size_hint: None, .16
            width: 225
            on_press:
                Timer(root, self, 5, [0.17, 1.7, 0, 1]).start()

        Button:
            text: "2"
            size_hint: None, .16
            width: 225
            on_press:
                Timer(root, self, 10, [1.7, 0, 1.7, 1]).start()


<Timer>:
    canvas.before:
        Color:
            rgba: 0, 0, 0.5, 1  # 50% blue
        Rectangle:
            size: self.size
            pos: self.pos

    size_hint: 0.3, .1
    font_size: 50
    pos_hint: {'center_x': 0.5, 'center_y': 0.5}

输出

Img01 - Button 1 pressed Img02 - Button 2 pressed