Kivy(Python)-椭圆点击事件

时间:2018-12-11 00:40:10

标签: python oop canvas kivy

我正在尝试将用JavaScript编写的a simple canvas app的开头翻译为Kivy框架。我已经能够沿圆的周长分布顶点,但是无论是用Python还是Kv语言尝试,我都未能在每个顶点上注册点击事件。一个好的开始可能是更改任何单击的顶点的大小。欢迎任何提示,反馈,解决方案。

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.graphics import *
from kivy.properties import NumericProperty
from random import randint
import math

class Vertex(Widget):
    def __init__(self, position=(50,50), **kwargs):
        super(Vertex, self).__init__(**kwargs)
        self.position = position
        self.size = (10,10)


    def draw(self):
     with self.canvas:
        Color(1., 0, 0)
        Ellipse(pos=self.position, size=self.size)


class ChromaticCircle(Widget):
    vertices = []

    def __init__(self, radius=100, **kwargs):
        super(ChromaticCircle, self).__init__(**kwargs)
        self.radius = radius
        self.draw()

    def draw(self):
        interval = (math.pi * 2) / 12

        with self.canvas:
            Color(1., 0, 0)

            for i in range(1, 13):
                angle = (math.radians(360) / 12) * (i + 9)
                position = ((self.center_x + 200) + (self.radius*math.cos(angle)), (self.center_y + 200)+(self.radius)*math.sin(angle))
                self.vertices.append(Vertex(position))

            for j in range(len(self.vertices)):
                self.vertices[j].draw()


class MyApp(App):
    def build(self):
        return ChromaticCircle()

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

1 个答案:

答案 0 :(得分:1)

通过使用Vertex方法中的collide_point方法来检查on_touch_down事件是否在Touch中发生,可以捕获Vertex小部件上的点击:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.graphics import *
from kivy.properties import NumericProperty
from random import randint
import math

class Vertex(Widget):
    def __init__(self, position=(50,50), **kwargs):
        super(Vertex, self).__init__(**kwargs)
        self.position = position
        self.size = (10,10)
        self.pos = position    # need to set the `pos` as `collide_point` uses it

    def draw(self):
     with self.canvas:
        Color(1., 0, 0)
        Ellipse(pos=self.position, size=self.size)


class ChromaticCircle(Widget):
    vertices = []

    def __init__(self, radius=100, **kwargs):
        super(ChromaticCircle, self).__init__(**kwargs)
        self.radius = radius
        self.draw()

    def on_touch_down(self, touch):
        # check if the touch is on a Vertex
        for vert in self.vertices:
            if vert.collide_point(touch.x, touch.y):
                print('click on vertex: ' + str(vert.pos))
                return True
        return super(ChromaticCircle, self).on_touch_down(touch)

    def draw(self):
        interval = (math.pi * 2) / 12

        with self.canvas:
            Color(1., 0, 0)

            for i in range(1, 13):
                angle = (math.radians(360) / 12) * (i + 9)
                position = ((self.center_x + 200) + (self.radius*math.cos(angle)), (self.center_y + 200)+(self.radius)*math.sin(angle))
                print('adding vertex at ' + str(position))
                self.vertices.append(Vertex(position))

            for j in range(len(self.vertices)):
                self.vertices[j].draw()


class MyApp(App):
    def build(self):
        return ChromaticCircle()

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

您可能还需要考虑一些其他细节。 pos的{​​{1}}是左下角,因此您的顶点位置不在绘制的Ellipse的中心。