Kivy меняет цвет пользовательской кнопки при нажатии

#python #kivy

#python #kivy

Вопрос:

Само собой разумеется, что я новичок в kivy, пытаюсь написать простой графический интерфейс с треугольными кнопками (и я хочу, чтобы они были приличными, а не просто изображениями, которые все еще являются квадратным холстом, который можно щелкнуть с треугольной части). Итак, я нашел этот отличный код, который создает треугольник и получает область, доступную для просмотра.

По сути, я просто хочу, чтобы она меняла цвета при нажатии (и возвращалась обратно при нажатии), и я слишком новичок, чтобы заставить это работать.

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

Я думаю, что я просто ошибся в этой строке:

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

но, черт возьми, я действительно не знаю. Любая помощь будет оценена

Ответ №1:

Вы уже находитесь в виджете, перейдите прямо к нему, а не через ids него. Ids предназначены для свойства id , установленного в дочерних элементах виджета на языке kv, например, если у вашего TriangleButton был дочерний Image элемент с an id: myimage , вы бы получили его с помощью этого:

 self.ids.myimage
 

Поэтому достаточно удалить ненужный материал:

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

Также приятно печатать то, что вы на самом деле ищете — если он печатает какой-то объект, или если эта вещь даже не существует. И привязка приятнее, чем вводить что-то вручную on_press 🙂

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