使用自定义宽度设置Kivy Bezier曲线的动画?(有点傻的问题)

2024-05-05 12:08:49 发布

您现在位置:Python中文网/ 问答频道 /正文

更新:在与其他人讨论后,我认为这是一个有点愚蠢的问题。我想用更改的宽度设置贝塞尔曲线的动画,但它没有宽度属性。使用直线贝塞尔,我可以改变宽度,但不能设置动画


我不能像Line那样改变Bezier曲线的witdh
代码如下:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import *

class MyLayout(Widget):
    def __init__(self):
        super(MyLayout, self).__init__()
        with self.canvas:
            self.L=Bezier(points=[200,450,500,300,600,150],width=12)
            self.k=Line  (bezier=[100,350,400,200,500,50 ],width=12)

class MyApp(App):
    def __init__(self):
        super(MyApp, self).__init__()
    def build(self):
        return MyLayout()

if __name__=="__main__":
    MyApp().run()

最后: MyApp

问题是,

上面的曲线不是width=12

我想这是因为Kivy的Bezier类没有属性width,因为当我在kvlang上执行时,它会给我AttributeError: 'kivy.graphics.vertex_instructions.Bezier' object has no attribute 'width'。那么,为什么不将Linebezier一起使用呢?我想在它上面使用Animation,当我试图用bezierLine上时,我得到AttributeError: attribute 'bezier' of 'kivy.graphics.vertex_instructions.Line' objects is not readable

所以这个问题,

如何更改{}的{}。如果这是不可能的,有没有什么方法,比如找到给定x的cruve(或ys)的y,这样我就可以在这些点上放置Ellipse,并调整它们的大小以模拟宽度

谢谢并请原谅我的英语


Tags: fromimportself宽度initdeflinewidth
2条回答

该行可以使用bezier:,例如:

Line:
    bezier:[n1,n2,n3,n4]
    width:3

这是一个Line,不是一个Bezier,但是你得到了相同的结果

一个例子:

from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout

posicao=[]
class Draw(BoxLayout):
    def __init__(self, **kwargs):
        super(Draw, self).__init__(**kwargs)
    
    def on_touch_down(self,touch):
        posicao.append(touch.pos)
        
    def on_touch_up(self,touch):
        posicao.clear()
        
    def on_touch_move(self,touch):
        Line = Builder.load_string(
"""
FloatLayout:
    canvas:
        Color:
            rgba:11,.1,1,1
        Line:
            points: {pos}
            width:14
""".format(pos=(touch.pos, posicao[0])))
        self.add_widget(Line)
        posicao.clear()
        posicao.append(touch.pos)
        
class Code(App):
    def build(self):
        return Draw()
        
if __name__ == '__main__':
    Code().run()

我 或:

from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import *

posi = []

Builder.load_string(
"""
<Draw>:
    
""")
class Draw(BoxLayout):
    def __init__(self, **kwargs):
        super(Draw, self).__init__(**kwargs)
    
    def on_touch_down(self,touch):
        posi.clear()
        posi.append(touch.pos)
        
    def on_touch_up(self,touch):
        posi.clear()
        
    def on_touch_move(self,touch):
        with self.canvas:
            Line(points=[posi[0], touch.pos],width=14)
        posi.clear()
        posi.append(touch.pos)
            
class Code(App):
    def build(self):
        return Draw()
        
if __name__ == '__main__':
    Code().run()

Bezier没有width属性,但是Line有。因此,您可以设置width的动画。一种简单的方法是设置一个保持宽度的NumericProperty的动画。下面是代码的一个修改版本,它可以:

from kivy.animation import Animation
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.uix.widget import Widget
from kivy.graphics import *

class MyLayout(Widget):
    line_width = NumericProperty(12)
    def __init__(self):
        super(MyLayout, self).__init__()
        with self.canvas:
            self.L=Bezier(points=[200,450,500,300,600,150],width=self.line_width)
            self.k=Line  (bezier=[100,350,400,200,500,50 ],width=self.line_width)

    def on_line_width(self, instance, new_width):
        self.k.width = new_width

class MyApp(App):

    def build(self):
        Clock.schedule_once(self.anim)
        return MyLayout()

    def anim(self, dt):
        a = Animation(line_width=3)
        a.start(self.root)

if __name__=="__main__":
    MyApp().run()

如果您在kv中构建Line,那么您甚至不需要on_line_width()方法,因为kivy将为您进行绑定

相关问题 更多 >