简体   繁体   中英

Kivy changing color of a custom button on press

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.

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.

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('''
<TriangleButton>:
    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 > min(p1y, p2y):
            if y <= max(p1y, p2y):
                if x <= max(p1x, p2x):
                    if p1y != p2y:
                        xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                    if p1x == p2x or x <= 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)))

I'm thinking I just have this line wrong:

self.ids.trianglething.canvas.triangle_down_color = (1,0,1,1)

but heck I don't really know. Any help would be appreciated

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

self.ids.myimage

Therefore removing the unnecessary stuff is enough:

self.triangle_down_color = (1,0,1,1)

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 on_press :)

t = TriangleButton()
t.bind(on_press=function)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM