【问题标题】:Python Kivy: animation won't run when called from clock eventPython Kivy:从时钟事件调用时动画不会运行
【发布时间】:2020-08-13 02:47:22
【问题描述】:

我正在尝试通过使用名为“级别”的数字属性更改其角度来定期运行画布圆线的动画,因此它通过创建时钟对象每秒刷新一次,但动画根本不会运行。另一方面,当用户在文本输入中输入“r”时,我还从 .kv 文件中调用了一种不同的方法,该文本输入为“级别”数字属性设置动画并且动画运行完美。 我注意到在这两种情况下,“级别”的值是不同的,就好像有两个不同的级别实例一样。我不明白发生了什么,有人可以阐明我做错了什么吗?

请注意,动画正在影响“转速计”注释部分下我的 .kv 文件中 ID 为“gauge and needle”的小部件

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】:

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

    蟒蛇:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-22
      • 2017-09-16
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      相关资源
      最近更新 更多