3

I'm trying to periodically run the animation of canvas circle line by changing its angle using a numeric property called "level" so it refreshes every second by creating a Clock object but the animation simply won't run. In the other hand I also have a different method been called from the .kv file when user inputs 'r' in a text input that animates that "level" numeric property and the animation runs perfectly. I've noticed that in both cases the value of "level" is different as if there were 2 different instances of level. I do not understand what is going on, can some one shed some light on what I'm doing wrong?

Notice that the animation is affecting the widgets with id "gauge and needle" on my .kv file under the "tachometer" commented section

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)

1 Answers1

2

The solution I found was creating object properties so I could have specific custom properties for each widget I needed to add animation.

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)