Нарисуйте круг радиуса, который равен значению ползунка, нарисованного на другом классе виджета - PullRequest
0 голосов
/ 03 июля 2019

Я включил функцию рисования круга в моем приложении. Однако радиус и длина дуги окружности определяются через значение ползунка. Я хочу, чтобы мой круг нарисовался на другом виджете, а слайдер - на другом.

Вот мой файл Kv, включающий класс виджетов с ползунком

<Compass_slider>:
    radius:radius
    arc:arc
    canvas:
        Color:
            rgb: 0.8, 0.8, 0.8,1    

        Rectangle:
            pos:root.pos
            size:root.size
    BoxLayout:
        pos:
            root.pos
        size:
            root.size
        orientation: 'vertical'
        Slider:
            id:radius
            min: 0.
            max: 50.
            step:1
            value_track_color:1,0,0,1
        Label:
            color:1,0,0,1
            pos:root.pos
            text: 'radius = {}'.format(radius.value)

        Slider:
            id: arc
            min:0.
            max: 360.
            value:0
            step:1
            value_track_color:1,0,0,1

        Label:
            color:1,0,0,1
            pos:root.pos
            text: 'arc = {}'.format(arc.value)

и мой python-файл класса виджетов, где я хочу, чтобы мой круг рисовался с радиусом и дугой, определенной с помощью slider.Я также хотел бы быть центром круга в позиции touch_down.

class MyPaintWidget(Widget):
    global undolist
    global objects

    def __init__(self, **kwargs):
        super(MyPaintWidget, self).__init__(**kwargs)
        self.touch_init = 0, 0
        self.circle = Line()

    def undo(self, obj):
        if len(objects) > 0:
            item = objects.pop(-1)
            self.canvas.remove(item)

    def on_touch_down(self, touch):
        if icons["eraser"]:

            with self.canvas:
                Color(1, 1, 1, 1)
                Rectangle(pos=(touch.x - d, touch.y - d), size=(2 * d, 2 * d))

        elif icons["compass"]:
            pass

Я думаю, что-то вроде

elif icons["compass"]:
    Line(circle=(touch.x,touch.y,compass_slider().radius.value,0,compass_slider().arc.value))

1 Ответ

0 голосов
/ 04 июля 2019

Вот простое приложение, которое делает в основном то, что вы хотите. При этом используется свойство on_value события Slider и событие on_touch_down для запуска рисования дуги. Таким образом, любое изменение радиуса или дуги создаст новую дугу. Кроме того, любое событие касания будет рисовать дугу в этой позиции.

from kivy.app import App
from kivy.graphics.vertex_instructions import Line
from kivy.lang import Builder
from kivy.uix.widget import Widget


class MyPaintWidget(Widget):
    def __init__(self, **kwargs):
        super(MyPaintWidget, self).__init__(**kwargs)
        self.circle_center = None

    def draw_arc(self, *args):
        if len(args) > 0:
            # this is the result of a touch event
            if not self.collide_point(*args[0].pos):
                # touch was not within the MyPaintWidget
                return
            else:
                # set circle center to touch position
                self.circle_center = args[0].pos
        if self.circle_center is None:
            # default value for circle center
            self.circle_center = self.center

        # get the root widget (the FloatLayout)
        root = App.get_running_app().root

        # get the canvas of the MyPaintWidget
        can = root.ids.mypaintwidget.canvas

        # clear any previous drawing and draw a new arc
        can.clear()
        with can:
            Line(circle=(self.circle_center[0], self.circle_center[1], root.ids.radius.value, 0.0, root.ids.arc.value))


theRoot = Builder.load_string('''
FloatLayout:
    MyPaintWidget:
        id: mypaintwidget
        pos_hint: {'x':0.0, 'top':1.0}
        size_hint: 0.75, 1.0
        on_touch_down:
            self.draw_arc(args[1])
    BoxLayout:
        pos_hint: {'right':1.0, 'top':1.0}
        size_hint: 0.25, 1.0
        orientation: 'vertical'
        Slider:
            id:radius
            min: 0.
            max: 50.
            step:1
            value: 50
            value_track_color:1,0,0,1
            on_value: mypaintwidget.draw_arc()
        Label:
            color:1,0,0,1
            pos:root.pos
            text: 'radius = {}'.format(radius.value)

        Slider:
            id: arc
            min:0.
            max: 360.
            value:270
            step:1
            value_track_color:1,0,0,1
            on_value: mypaintwidget.draw_arc()

        Label:
            color:1,0,0,1
            pos:root.pos
            text: 'arc = {}'.format(arc.value)
''')


class ArcDrawApp(App):
    def build(self):
        return theRoot


ArcDrawApp().run()
...