Custom Shape Button

91 views
Skip to first unread message

Eoin Brennan

unread,
Aug 5, 2023, 5:14:53 PM8/5/23
to Kivy users support
I am trying to create a number of irregular rectangular buttons stacked on top of each other. I have achieved most of the task and the code is below, the code creates and saves .pngs for the various shapes then uses these shapes in the kivy app. I got the sizing and positioning the way I want it but the problem I am having is that the widget that is the image seems to be rectangular, so therefore the widgets overlap even though the shapes dont. The problem that this creates is the the on_press() function is not always triggering the correct button especially near the edges as can be seen by the image here. (The red box was hand drawn on the screenshot to show the shape of the widget!)

ScreenShot

The idea I am trying to achieve is that pressing inside the shape will active the button. Any ideas how I can reduce the area to just inside the shape.

Thanks

Full code is in stack here....
https://stackoverflow.com/questions/76843554/kivy-custom-shape-button-still-is-rectangular-widgt

elli...@cox.net

unread,
Aug 5, 2023, 5:46:47 PM8/5/23
to kivy-...@googlegroups.com

You can not use the provided on_press and on_release methods, they are based on rectangle (as you have discovered). 

 

Instead, you will need to create new events using the on_touch_down and on_touch_up methods.  You will also need to create your own test to see if the shape was pressed.  That is going to require a little geometry. 

 

Looking at the image I see there is a triangle area above and below the stripe.  I imagine it will be easier to test for a point inside a triangle than inside a parallelogram.    So if the widget rectangle is touched and the point is not in the lower or upper triangle, then your parallelogram has been touched.

 

If you want to get fancy you can dispatch your own on_press and on_release events.

 

Ask a follow-up if you need more help.

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/4e97bc77-bdbb-40a1-ba77-35ef9ad6737dn%40googlegroups.com.

elli...@cox.net

unread,
Aug 6, 2023, 12:34:38 AM8/6/23
to kivy-...@googlegroups.com

Here is a working example that uses a circle, rather than a parallelogram.

 

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ColorProperty, NumericProperty
from kivy.uix.label import Label

kv =
"""
<CircleButton>:
    size_hint: None, None
    size: self.radius * 2, self.radius * 2
    canvas.before:
        Color:
            rgba: self._button_color
        Ellipse:
            size: self.size
            pos: self.pos

AnchorLayout:
    CircleButton:
        text: 'Push'
        radius: dp(75)
        on_press: print('Button Pressed')
        on_release: print('Button Released')
"""


class CircleButton(Label):
    radius = NumericProperty(
50)
    normal_color = ColorProperty(
'gray')
    down_color = ColorProperty(
'blue')
    _button_color = ColorProperty(
'gray')

   
def __init__(self, **kwargs):
       
self.register_event_type('on_release')
       
self.register_event_type('on_press')
       
super().__init__(**kwargs)

   
def on_press(self):
       
pass

    def
on_release(self):
       
pass

    def
is_inside_circle(self, touch_x, touch_y):
        dx =
abs(touch_x - self.center_x)
        dy =
abs(touch_y - self.center_y)
       
return dx ** 2 + dy ** 2 <= self.radius ** 2

   
def on_touch_down(self, touch):
       
if self.is_inside_circle(*touch.pos):
            touch.grab(
self)
           
self._button_color = self.down_color
           
self.dispatch('on_press')
           
return True
       
super().on_touch_down(touch)

   
def on_touch_up(self, touch):
       
if touch.grab_current is self:
           
self._button_color = self.normal_color
           
self.dispatch('on_release')
           
return True
        return
super().on_touch_up(touch)


class CircleButtonExampleApp(App):
   
def build(self):
       
return Builder.load_string(kv)


CircleButtonExampleApp().run()

 

 

From: kivy-...@googlegroups.com <kivy-...@googlegroups.com> On Behalf Of Eoin Brennan
Sent: Saturday, August 5, 2023 2:15 PM
To: Kivy users support <kivy-...@googlegroups.com>
Subject: [kivy-users] Custom Shape Button

 

I am trying to create a number of irregular rectangular buttons stacked on top of each other. I have achieved most of the task and the code is below, the code creates and saves .pngs for the various shapes then uses these shapes in the kivy app. I got the sizing and positioning the way I want it but the problem I am having is that the widget that is the image seems to be rectangular, so therefore the widgets overlap even though the shapes dont. The problem that this creates is the the on_press() function is not always triggering the correct button especially near the edges as can be seen by the image here. (The red box was hand drawn on the screenshot to show the shape of the widget!)

--

Reply all
Reply to author
Forward
Message has been deleted
0 new messages