У меня возникли проблемы с изменением цвета простого виджета в Kivy. Я могу установить цвет при создании виджета, но потом не могу его изменить.
Вот простой файл определения макета circletest.kv
. Он определяет круг, в котором цвет (фактически только r, из rgba), положение и размер связаны с переменными в классе виджетов.
#:kivy 1.4.1
<CircleWidget>:
canvas:
Color:
rgba: self.r,1,1,1
Ellipse:
pos: self.pos
size: self.size
Здесь приложение circletest.py
. Он создает и отображает простой виджет. Цвет и положение успешно задаются при создании объекта. При щелчке виджета виджет может изменить свою собственную позицию, но когда я пытаюсь изменить цвет, ничего не происходит.
import kivy
kivy.require('1.4.1')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
Builder.load_file('circletest.kv')
class CircleWidget(Widget):
def __init__(s, **kwargs):
s.size= [50,50]
s.pos = [100,50]
s.r = 0
super(CircleWidget, s).__init__(**kwargs)
def on_touch_down(s, touch):
if s.collide_point(touch.x,touch.y):
s.pos = [s.pos[1],s.pos[0]] # This works
s.r = 1.0 # <---- This does nothing!
class TestApp(App):
def build(s):
parent = Widget()
w = CircleWidget()
parent.add_widget(w)
return parent
if __name__ == '__main__':
TestApp().run()
Может ли кто-нибудь увидеть проблему?
UPDATE
Пока не уверен, что ответ на этот вопрос, но у меня есть работа вокруг:
В файле .kv я указал цвет на переменную в моем объекте. Работает для извлечения исходного цвета:
Color:
rgba: self.col
Когда я хочу изменить цвет из .py файла, я просматриваю все инструкции на холсте и изменяю первый тип "Цвет". Очевидно, что это взломать и не будет работать с виджетами с более чем одним свойством Color:
:
for i in s.canvas.get_group(None):
if type(i) is Color:
i.r, i.g, i.b, i.a = v
break
Я завернул все в свойство, чтобы оно было аккуратным:
class CircleWidget(Widget):
def get_col(s):
return s._col
def set_col(s,v):
for i in s.canvas.get_group(None):
if type(i) is Color:
i.r, i.g, i.b, i.a = v
break
s._col = v
col = property(get_col, set_col)
def __init__(s, **kwargs):
s.size= [50,50]
s.pos = [100,50]
s._col = (1,1,0,1)
super(CircleWidget, s).__init__(**kwargs)
def on_touch_down(s, touch):
if s.collide_point(touch.x,touch.y):
s.col = (s.col[::-1]) # Set to some other color
Кажется, сейчас работает. Пожалуйста, дайте мне знать, если вы знаете лучший способ сделать это. Я уверен, что должен быть более простой способ, и что я пропускаю что-то очевидное!