Python Kivy: анимация не запускается при вызове с часового события - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь периодически запускать анимацию линии круга холста, изменяя ее угол, используя свойство Numberri c, называемое «уровень», поэтому оно обновляется каждую секунду, создавая объект Clock, но анимация просто не запускается. С другой стороны, у меня также был вызван другой метод из файла .kv, когда пользователь вводит «r» в текстовом вводе, который анимирует это свойство «level» цифра c, и анимация работает отлично. Я заметил, что в обоих случаях значение «уровень» отличается, как если бы было 2 разных экземпляра уровня. Я не понимаю, что происходит, может кто-нибудь пролить свет на то, что я делаю неправильно?

Обратите внимание, что анимация влияет на виджеты с идентификатором «калибр и игла» в моем файле .kv в разделе с комментариями «тахометр»

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 Ответ

0 голосов
/ 04 мая 2020

Решением, которое я нашел, было создание свойств объекта, чтобы можно было задать c настраиваемые свойства для каждого виджета, который мне нужен для добавления анимации.

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)
...