Kivy的新手试图创造秒表

时间:2018-01-02 11:21:56

标签: python-3.x kivy kivy-language

我试图在Kivy制作一个秒表。我已经在Sublime Text 3上完成了一个骨架(如下面的代码所示)。当我在Sublime Text上运行代码时,会打开一个窗口,但Python在4.1s中崩溃。

以下是相关代码:

import kivy

from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.properties import NumericProperty

from kivy.lang import Builder

import time

class CrudeTimerGrid(GridLayout):
    # Initialise timer with input start time
    def __init__(self,start_time):
        time = NumericProperty(start_time)

    def tick(self):
        if self.time > 0:
            self.time -= 1
        else:
            pass

    def start(self):
        Clock.schedule_interval(self.tick,1)

    def pause(self):
        Clock.unschedule()

    # incomplete code
    def reset(self):
        pass


class CrudeTimerApp(App):
    def build(self):
        # Testing timer by initialising timer with 20 seconds
        return CrudeTimerGrid(20)

Builder.load_string('''
<CrudeTimerGrid>
    id: timer
    rows: 2
    # insert formatting here

    BoxLayout:
        Label:
            text: timer.time

    BoxLayout:

        Button:
            text: "Start"
            on_press: timer.start()

        Button:
            text: "Pause"
            on_press: timer.pause()

        Button:
            text: "Reset"
            on_press: timer.reset()
''')

CrudeTimerApp().run()
也是StackOverflow的新手,所以如果需要任何其他信息,请告诉我。谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

主要问题在于:

def __init__(self,start_time):
    time = NumericProperty(start_time)

您应该在课程级别定义Kivy属性,请阅读this。如果你改变它,代码将停止崩溃:

class CrudeTimerGrid(GridLayout):
    time = NumericProperty(0)

为了使它最终有效,你还应该做一些其他的改变,这里是完整的代码版本:

import kivy

from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.properties import NumericProperty

from kivy.lang import Builder

import time

class CrudeTimerGrid(GridLayout):
    time = NumericProperty(0)

    def tick(self, *_):
        if self.time > 0:
            self.time -= 1
        else:
            pass

    def start(self, *_):
        self.cb = Clock.schedule_interval(self.tick,1)

    def pause(self):
        Clock.unschedule(self.cb)

    # incomplete code
    def reset(self, *_):
        pass


class CrudeTimerApp(App):
    def build(self):
        # Testing timer by initialising timer with 20 seconds
        return CrudeTimerGrid(time=20)

Builder.load_string('''
<CrudeTimerGrid>
    id: timer
    rows: 2
    # insert formatting here

    BoxLayout:
        Label:
            text: str(timer.time)

    BoxLayout:

        Button:
            text: "Start"
            on_press: timer.start()

        Button:
            text: "Pause"
            on_press: timer.pause()

        Button:
            text: "Reset"
            on_press: timer.reset()
''')

CrudeTimerApp().run()

<强> UPD:

  

任何想法为什么2个参数首先输入到tick中?

tick传递给Clock.schedule_interval进行调用。该函数使用附加参数调度它的回调(Kivy中的许多其他函数也可以)。您可以在documentation中阅读更多相关信息。

  

您定义了self.cb以便在Clock.unschedule中引用它,   正确的吗?

您可以使用不同的时间间隔调度许多不同的函数,多次调用Clock.schedule_interval。但Clock.unschedule怎么能知道哪些具体的计划未计划?为了使Clock.unschedule知道要取消预定的内容,您应该将Clock.schedule_interval返回的值传递给它。这是documentation section这个机制描述的地方。