Python Kivy:当从时钟事件中调用时,动画不会运行。

问题描述 投票:0回答:1

我试图通过使用一个名为 "level "的数字属性改变画布圆线的角度来周期性地运行动画,因此它每秒钟都会通过创建一个时钟对象来刷新,但动画根本无法运行。另一方面,当用户在文本输入中输入'r'时,我也从.kv文件中调用了一个不同的方法,使 "level "数字属性产生动画,动画完美地运行。我不明白这是怎么回事,有谁能给我一些启示,我到底做错了什么?

请注意,这个动画影响了我的.kv文件中 "转速表 "注释部分下的id为 "仪表和针 "的部件。

import kivy
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.properties import *
from kivy.animation import Animation
import kivy.graphics
from kivy.clock import Clock


from math import cos, sin, pi
from functools import partial



import random


def rpm_conversion(rpm):
    return (rpm * (180.5/8000) -135.5)



####################################################
#---------------------- GUI -----------------------#


class DataWindow(GridLayout):

    def rpmupdate(self,dt):
        rand = random.randint(0,8000)
        gaugranim = Animation(level = rpm_conversion(float(rand)))
        print("Timer triggered: " + str(self.level))
        self.rpm = int(rand)
        gaugranim.start(self)




    def on_enter(self, value):
        print(value[5:] )
        self.display.text = "ecu> "
        rand = random.randint(0,8000)
        if(value[5:] == "r"):
            anim = Animation(level = rpm_conversion(float(rand)) )
            print("User triggered: " + str(self.level))
            self.rpm = int(rand)

        anim.start(self)



    #Keeps user from deleting name in console
    def bashlook(self,value, crs):
        if(value[:5] != 'ecu> '):
            self.display.text = "ecu> "



class OpensecuApp(App):
    def build(self):
        clock = DataWindow()
        Clock.schedule_interval(clock.rpmupdate, 2)
        return DataWindow()


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

.kv:

#:import math math

[GaugeNumber@Label]:
    text: str(ctx.i)
    pos_hint: {"center_x": 0.5+0.42*math.sin(math.pi/8*(ctx.i-6)), "center_y": 0.5+0.42*math.cos(math.pi/8*(ctx.i-6))}
    font_size: self.height/24


<DataWindow>:
    id: opensecu
    display: cmd


    level: -135
    rpm: 0

    # Main window
    rows:2
    spacing: 10
    padding: 10

    canvas:
        Color:
            rgba: 0.1,0.1,0.1,1
        Rectangle:
            pos: self.pos
            size: self.size


##########################################################

    GridLayout:
        size_hint: 1,1
        cols: 3

#-------------------------- Data -----------------------------#
        #Data
        BoxLayout:
            canvas:
                Color:
                    rgba: 0.12,0.1195,0.122,1
                Rectangle:
                    pos: self.pos
                    size: self.size
            Label:
                text: "I'm label 1"



#---------------------- Tachometer RPM ------------------------#
        BoxLayout:
            size_hint: 1.5,1

            canvas.before:
                Color:
                    rgba: 0.12,0.1195,0.122,1
                Rectangle:
                    pos: self.pos
                    size: self.size

            AnchorLayout:
                anchor_x: 'center'
                anchor_y: 'center'

                FloatLayout: #gauges numers
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.95 ) , (min(self.parent.size) * 0.95 )
                    GaugeNumber:
                        i: 0
                    GaugeNumber:
                        i: 1
                    GaugeNumber:
                        i: 2
                    GaugeNumber:
                        i: 3
                    GaugeNumber:
                        i: 4
                    GaugeNumber:
                        i: 5
                    GaugeNumber:
                        i: 6
                    GaugeNumber:
                        i: 7
                    GaugeNumber:
                        i: 8

                AnchorLayout: #gauges dots
                    anchor_x: 'center'
                    anchor_y: 'center'
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.68 ) , (min(self.parent.size) * 0.68 )
                    Image:
                        source: "resources/gauge.png"
                        size: self.texture_size


                AnchorLayout: #gauges level rail

                    anchor_x: 'center'
                    anchor_y: 'center'

                    canvas.before:
                        Color:
                            rgba: 0.1,0.1,0.1,1
                        Line:
                            width: min(self.size)/15
                            circle:
                                (self.center_x, self.center_y, min(self.width, self.height)
                                / 2, -135.5, 45, 500)
                            cap: 'none'

                    size_hint:None,None
                    size: (min(self.parent.size) * 0.5 ) , (min(self.parent.size) * 0.5 )


                AnchorLayout: #gauge's levels
                    id: gauge
                    anchor_x: 'center'
                    anchor_y: 'center'
                    canvas.before:
                        Color:
                            rgba: 0,0.93,1,0.5
                        Line:
                            width: min(self.size)/15
                            circle:
                                (self.center_x, self.center_y, min(self.width, self.height)
                                / 2, -135, root.level , 50)
                            cap: 'none'

                    size_hint:None,None
                    size: (min(self.parent.size) * 0.5 ) , (min(self.parent.size) * 0.5 )


                AnchorLayout: #blue line in gauge
                    anchor_x: 'center'
                    anchor_y: 'center'
                    canvas.before:
                        Color:
                            rgba: 0,0.93,1,0.5
                        Line:
                            width: min(self.width, self.height) / 100
                            circle:
                                (self.center_x, self.center_y, min(self.width, self.height)
                                / 2, 0, 360 , 50)
                            cap: 'none'

                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , (min(self.parent.size) * 0.38 )



                BoxLayout: #gauge real time RPMS
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , ((min(self.parent.size) * 0.38) )
                    Label:
                        text: str(int(root.rpm))
                        pos_hint: {"center_x": 0.5, "center_y": 0.65}
                        font_size: self.height / 6

                BoxLayout:#gauges RPM note
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , ((min(self.parent.size) * 0.38) )
                    Label:
                        text: "RMP"
                        pos_hint: {"center_x": 0.5, "center_y": 0.35}
                        font_size: self.height / 12


                BoxLayout:#gauges x1000
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , ((min(self.parent.size) * 0.38) )
                    Label:
                        text: "x1000"
                        pos_hint: {"center_x": 0.5, "center_y": 0.25}
                        font_size: self.height / 10



                FloatLayout: #gauges needle
                    id: needle
                    anchor_x: 'center'
                    anchor_y: 'center'
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.60 ) , (min(self.parent.size) * 0.60 )

                    Image:
                        source: "resources/needle.png"
                        size: self.texture_size
                        pos_hint: {'center_x': .5, 'center_y': .5}
                        canvas.before:
                            PushMatrix
                            Rotate:
                                angle: (root.level)* (-1)
                                origin: self.center
                        canvas.after:
                            PopMatrix


#------------------------ Volumetric Efficiency Table -------------------------#

        BoxLayout:
            canvas:
                Color:
                    rgba: 0.12,0.1195,0.122,1
                Rectangle:
                    pos: self.pos
                    size: self.size
            Label:
                text: "I'm label 3"



###################################################################


#------------------------ Console -------------------------#
    BoxLayout:
        size_hint: 1,0.3
        canvas:
            Color:
                rgba: 0.12,0.1195,0.122,1
            Rectangle:
                pos: self.pos
                size: self.size

        TextInput:
            id: cmd
            text: "ecu> "
            background_color: 0.12,0.1195,0.122,1
            foreground_color: 1,1,1,1
            boold: 1
            padding: 15
            multiline: False
            on_text: opensecu.bashlook(self.text, self.cursor)
            on_text_validate: opensecu.on_enter(self.text)
            # on_key_down:opensecu.on_enter(self.text)
python animation properties kivy kivy-language
1个回答
2
投票

我找到的解决方案是创建对象属性,这样我就可以为每个我需要添加动画的widget拥有特定的自定义属性。

python:

import kivy
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.uix.textinput import TextInput
from kivy.properties import *
from kivy.animation import *
import kivy.graphics
from kivy.clock import Clock


from math import cos, sin, pi
from functools import partial



import random


def rpm_conversion(rpm):
    return (rpm * (180.5/8000) -135.5)


####################################################
#---------------------- GUI -----------------------#

class Gaugenumber(Label)


class OpensecuGauge(AnchorLayout):
    gauge_level = NumericProperty(-135)


    def gauge_anim(self,dt):
        anim = Animation(gauge_level = rpm_conversion(float(readings[0])), d=0.5 )
        anim.start(self)


class OpensecuNeedle(Image):
    needle_level = NumericProperty(-135)

    def needle_anim(self,dt):
        # print(level)
        anim = Animation(needle_level = rpm_conversion(float(readings[0])) , d=0.5)
        anim.start(self)


class OpensecuWindow(GridLayout):

    gauge = ObjectProperty(None)
    needle = ObjectProperty(None)



    def start(self):
        Clock.schedule_interval(self.gauge.gauge_anim, 0.5)
        Clock.schedule_interval(self.needle.needle_anim, 0.5)
        Clock.schedule_interval(self.rpm_update, 0.5)


    def rpm_update(self,dt):
        anim = Animation(rpm = float(readings[0]), d=0.5)
        anim.start(self)




    def on_enter(self, value):
        print(value[5:] )
        self.display.text = "ecu> "
        rand = random.randint(0,8000)
        # print(self.gauge.level)
        if(value[5:] == "r"):
            pass
        elif(value[5:]=="connect"):
            cnnct()
            self.start()
        elif(value[5:]=="exit"):
            stp()
        else:
            pass


    #Keeps user from deleting name in console
    def bashlook(self,value, crs):
        if(value[:5] != 'ecu> '):
            self.display.text = "ecu> "



class OpensecuApp(App):
    def build(self):
        # clock = OpensecuWindow()
        # Clock.schedule_interval(clock.gauge.rpmupdate, 2)
        connection = OpensecuWindow()
        connection.start()
        return OpensecuWindow()


if __name__ == '__main__':
    OpensecuApp().run()
    exit()

.kv:

#:import math math

[GaugeNumber@Label]:
    text: str(ctx.i)
    pos_hint: {"center_x": 0.5+0.42*math.sin(math.pi/8*(ctx.i-6)), "center_y": 0.5+0.42*math.cos(math.pi/8*(ctx.i-6))}
    font_size: self.height/24

<OpensecuGauge>:
    anchor_x: 'center'
    anchor_y: 'center'
    size_hint:None,None


<OpensecuNeedle>:
    source: "resources/needle.png"
    size: self.texture_size
    pos_hint: {'center_x': .5, 'center_y': .5}
    canvas.after:
        PopMatrix


<OpensecuWindow>:
    id: opensecu
    display: cmd
    needle: needle
    gauge: gauge

    # level: -135
    # needle_level: -135
    rpm: 0

    # Main windows
    rows:2
    spacing: 10
    padding: 10

    canvas:
        Color:
            rgba: 0.1,0.1,0.1,1
        Rectangle:
            pos: self.pos
            size: self.size


##########################################################

    GridLayout:
        size_hint: 1,1
        cols: 3

#-------------------------- Data -----------------------------#
        #Data
        BoxLayout:
            canvas:
                Color:
                    rgba: 0.12,0.1195,0.122,1
                Rectangle:
                    pos: self.pos
                    size: self.size
            Label:
                text: "I'm label 1"



#---------------------- Tachometer RPM ------------------------#
        BoxLayout:
            size_hint: 1.5,1

            canvas.before:
                Color:
                    rgba: 0.12,0.1195,0.122,1
                Rectangle:
                    pos: self.pos
                    size: self.size

            AnchorLayout:
                anchor_x: 'center'
                anchor_y: 'center'

                FloatLayout: #gauges numers
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.95 ) , (min(self.parent.size) * 0.95 )
                    GaugeNumber:
                        i: 0
                    GaugeNumber:
                        i: 1
                    GaugeNumber:
                        i: 2
                    GaugeNumber:
                        i: 3
                    GaugeNumber:
                        i: 4
                    GaugeNumber:
                        i: 5
                    GaugeNumber:
                        i: 6
                    GaugeNumber:
                        i: 7
                    GaugeNumber:
                        i: 8

                AnchorLayout: #gauges dots
                    anchor_x: 'center'
                    anchor_y: 'center'
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.68 ) , (min(self.parent.size) * 0.68 )
                    Image:
                        source: "resources/gauge.png"
                        size: self.texture_size


                OpensecuGauge: #gauges level rail

                    canvas.before:
                        Color:
                            rgba: 0.1,0.1,0.1,1
                        Line:
                            width: min(self.size)/15
                            circle:
                                (self.center_x, self.center_y, min(self.width, self.height)
                                / 2, -135.5, 45, 500)
                            cap: 'none'

                    size: (min(self.parent.size) * 0.5 ) , (min(self.parent.size) * 0.5 )


                OpensecuGauge: #gauges levels
                    id: gauge
                    canvas.before:
                        Color:
                            rgba: 0,0.93,1,0.5
                        Line:
                            width: min(self.size)/15
                            circle:
                                (self.center_x, self.center_y, min(self.width, self.height)
                                / 2, -135, self.gauge_level , 50)
                            cap: 'none'

                    size: (min(self.parent.size) * 0.5 ) , (min(self.parent.size) * 0.5 )


                AnchorLayout: #blue line in gauge
                    anchor_x: 'center'
                    anchor_y: 'center'
                    canvas.before:
                        Color:
                            rgba: 0,0.93,1,0.5
                        Line:
                            width: min(self.width, self.height) / 100
                            circle:
                                (self.center_x, self.center_y, min(self.width, self.height)
                                / 2, 0, 360 , 50)
                            cap: 'none'

                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , (min(self.parent.size) * 0.38 )



                BoxLayout: #gauge real time RPMS
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , ((min(self.parent.size) * 0.38) )
                    Label:
                        text: str(int(root.rpm))
                        pos_hint: {"center_x": 0.5, "center_y": 0.65}
                        font_size: self.height / 6

                BoxLayout:#gauges RPM note
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , ((min(self.parent.size) * 0.38) )
                    Label:
                        text: "RMP"
                        pos_hint: {"center_x": 0.5, "center_y": 0.35}
                        font_size: self.height / 12


                BoxLayout:#gauges x1000
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.38 ) , ((min(self.parent.size) * 0.38) )
                    Label:
                        text: "x1000"
                        pos_hint: {"center_x": 0.5, "center_y": 0.25}
                        font_size: self.height / 10



                FloatLayout: #gauges needle
                    anchor_x: 'center'
                    anchor_y: 'center'
                    size_hint:None,None
                    size: (min(self.parent.size) * 0.60 ) , (min(self.parent.size) * 0.60 )
                    OpensecuNeedle:
                        id: needle
                        canvas.before:
                            PushMatrix
                            Rotate:
                                angle: (self.needle_level)* (-1)
                                origin: self.center



#------------------------ Volumetric Efficiency Table -------------------------#

        BoxLayout:
            canvas:
                Color:
                    rgba: 0.12,0.1195,0.122,1
                Rectangle:
                    pos: self.pos
                    size: self.size
            Label:
                text: "I'm label 3"



###################################################################


#------------------------ Console -------------------------#
    BoxLayout:
        size_hint: 1,0.3
        canvas:
            Color:
                rgba: 0.12,0.1195,0.122,1
            Rectangle:
                pos: self.pos
                size: self.size

        TextInput:
            id: cmd
            text: "ecu> "
            background_color: 0.12,0.1195,0.122,1
            foreground_color: 1,1,1,1
            boold: 1
            padding: 15
            multiline: False
            on_text: opensecu.bashlook(self.text, self.cursor)
            on_text_validate: opensecu.on_enter(self.text)
            # on_key_down:opensecu.on_enter(self.text)
© www.soinside.com 2019 - 2024. All rights reserved.