Marc Maxmeister
Marc Maxmeister

Reputation: 4699

Avoid having my custom button bound to multiple instances of that button when pressed

My example seems to pass self in the button object (based on printing my_id to debug and it matching the my_id for each button, but when I click on "Option A" all 3 buttons animate. When I click on "Option B", B and C animate.

Why is the on_touch_down event trigging other buttons of the same RoundedButton class on the same page? (these are in a screen manager, not shown in code).

<RoundedButton@Button>:
    style: "elevated"
    background_color: (0, 0, 0, 0)
    background_normal: ""
    background_down: ""

    canvas.before:
        Color:
            rgba: (0.72, 0.68, 0.92, 1) if self.state == 'normal' else (0.33, 0.48, 0.92, 1)
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [20]
        Color:
            rgba: (0.72, 0.68, 0.92, 1)
        Line:
            rounded_rectangle: (self.pos[0], self.pos[1], self.size[0], self.size[1], 20)
            width: 1 if self.state == 'normal' else 5

...


                        MDBoxLayout:
                            orientation: 'horizontal'

                            RoundedButton:
                                my_id: 'optionA'
                                text: 'Option A'
                                size_hint: 0.15, 0.35
                                on_touch_down: app.animate_darken(self)

                            RoundedButton:
                                my_id: 'optionB'
                                text: 'Option B'
                                size_hint: 0.15, 0.35
                                on_touch_down: app.animate_darken(self)

                            RoundedButton:
                                my_id: 'optionC'
                                text: 'Option C'
                                size_hint: 0.15, 0.35
                                on_touch_down: app.animate_darken(self)

And elsewhere, that animate_darken function:

    def animate_darken(self, widget, fade_length=0.5, *args):
        print(widget.my_id)
        BG_color = widget.background_color
        A = Animation(
            background_color=(0,0,0,1),
            duration=fade_length #seconds
        )
        A += Animation(x=0, y=0, duration=0.3)
        A += Animation(background_color=BG_color) # reset it
        A.start(widget)

Q: How do I bind each RoundeButton only to that button, and animate it without affecting other buttons on the screen?

Upvotes: 0

Views: 24

Answers (1)

John Anderson
John Anderson

Reputation: 39082

The problem is that you are using on_touch_down in your kv. The on_touch_down event is received by every widget in the App. Notice that you don't even have to click on any Button to see your unwanted results. See the documentation:

on_touch_down(), on_touch_move(), on_touch_up() don’t do any sort of collisions. If you want to know if the touch is inside your widget, use collide_point().

The ButtonBehavior defines on_press and on_release events, so you should use these events instead.

Upvotes: 1

Related Questions