Kivy changing color of a custom button on press
<p>Goes without saying that I am new to kivy, trying to write a simple GUI with triangular buttons (and I want them to be decent, not just images that are still a square canvas that be clicked off the triangular part). So I found this great code that makes a triangle and gets the clickable area. </p>

<p>Basically I just want it to change colors when pressed (and revert back when unpressed) and I'm too newbish to get that to work. </p>



<pre class="lang-py prettyprint-override"><code>import kivy
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ListProperty
from kivy.vector import Vector
from kivy.lang import Builder

Builder.load_string('''
&lt;TriangleButton&gt;:
    id: trianglething
    # example for doing a triangle
    # this will automatically recalculate pX from pos/size
    #p1: 0, 0
    #p2: self.width, 0
    #p3: self.width / 2, self.height
    # If you use a Widget instead of Scatter as base class, you need that:
    p1: self.pos
    p2: self.right, self.y
    p3: self.center_x, self.top

    # draw something
    canvas:
        Color:
            rgba: self.triangle_down_color
        Triangle:
            points: self.p1 + self.p2 + self.p3
''')

def point_inside_polygon(x, y, poly):
    '''Taken from http://www.ariel.com.au/a/python-point-int-poly.html
    '''
    n = len(poly)
    inside = False
    p1x = poly[0]
    p1y = poly[1]
    for i in range(0, n + 2, 2):
        p2x = poly[i % n]
        p2y = poly[(i + 1) % n]
        if y &gt; min(p1y, p2y):
            if y &lt;= max(p1y, p2y):
                if x &lt;= max(p1x, p2x):
                    if p1y != p2y:
                        xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                    if p1x == p2x or x &lt;= xinters:
                        inside = not inside
        p1x, p1y = p2x, p2y
    return inside

class TriangleButton(ButtonBehavior, Widget):
    triangle_down_color = ListProperty([1,1,1,1])
    p1 = ListProperty([0, 0])
    p2 = ListProperty([0, 0])
    p3 = ListProperty([0, 0])

    def changecolor(self, *args):
        print "color"
        self.ids.trianglething.canvas.triangle_down_color = (1,0,1,1)

    def collide_point(self, x, y):
        x, y = self.to_local(x, y)
        return point_inside_polygon(x, y,
                self.p1 + self.p2 + self.p3)  

if __name__ == '__main__':
    from kivy.base import runTouchApp

    runTouchApp(TriangleButton(on_press=TriangleButton.changecolor,size_hint=(None,None)))
</code></pre>

<p>I'm thinking I just have this line wrong:</p>

<pre class="lang-py prettyprint-override"><code>self.ids.trianglething.canvas.triangle_down_color = (1,0,1,1)
</code></pre>

<p>but heck I don't really know. Any help would be appreciated</p>

<p>You are already in the widget, go directly for it, not through <code>ids</code>. <code>Ids</code> are for property <code>id</code> set in the children of a widget in kv language e.g. if your TriangleButton had a child <code>Image</code> with an <code>id: myimage</code>, you'd get it with this:</p>

<pre><code>self.ids.myimage
</code></pre>

<p>Therefore removing the unnecessary stuff is enough:</p>

<pre><code>self.triangle_down_color = (1,0,1,1)
</code></pre>

<p>It's also nice to print what you are actually looking for - if it prints some object, or if that thing doesn't even exist. And binding is nicer than putting something manually into <code>on_press</code> :)</p>

<pre><code>t = TriangleButton()
t.bind(on_press=function)
</code></pre>

python kivy