【问题标题】:Kivy - Timer Integration in FloatLayoutKivy - FloatLayout 中的计时器集成
【发布时间】:2019-02-26 20:30:24
【问题描述】:

问题很简单,让 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。

请帮忙!

【问题讨论】:

  • 什么是t1???
  • 如果你在 .py 上向下滚动,t1 被定义为 Timer1 类。

标签: python layout timer kivy kivy-language


【解决方案1】:

解决方案

  1. 将定时器标签的设计视图从 Python 代码移动到 kv 文件中。
  2. class Timer 添加构造函数并接受参数,root, instance, duration, bg_colour
  3. 在 kv 文件中,在实例化 Timer 时传递参数 root (screen 'cont')、按钮实例、持续时间、背景颜色
  4. 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}

输出

【讨论】:

【解决方案2】:

使其工作的一种方法是让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 文件以创建根小部件(消除 &lt;&gt; 周围的 ContScreen)。
  2. 通过将t1.start() 替换为root.start_timer() 来更改.kv 文件中按钮的on_press
  3. XGApp 类中的build 方法中消除t1 = Timer1() 语句。

另一种方法是在.kv 文件中创建Timer1,并在按下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

【讨论】:

  • 您能描述一下在.kv 中创建Timer1 的过程吗?我会尝试这两种方法。
  • 将该信息添加到我的答案中。
猜你喜欢
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 2017-06-17
  • 1970-01-01
相关资源
最近更新 更多