問題描述
我無法在 Kivy 中更改簡單小部件的顏色.我可以在創建小部件時設置顏色,但之后無法更改.
I'm having trouble changing the color of a simple widget in Kivy. I can set the color when I create the widget, but I can't change it afterwards.
這里是簡單的布局定義文件circletest.kv
.它定義了一個圓圈,其中顏色(實際上只是 r,來自 rgba)、位置和大小都鏈接到小部件類中的變量.
Here is the simple layout definition file circletest.kv
. It defines a circle where the color (actually just the r, from rgba), position and size are all linked to variables in the widget class.
#:kivy 1.4.1
<CircleWidget>:
canvas:
Color:
rgba: self.r,1,1,1
Ellipse:
pos: self.pos
size: self.size
這是應用程序 circletest.py
.它創建并顯示簡單的小部件.創建對象時成功設置顏色和位置.單擊小部件時,小部件可以更改它自己的位置,但是當我嘗試更改顏色時,什么也沒有發生.
Here's the application circletest.py
. It creates and displays the simple widget. The color and position are successfully set when the object is created. When the widget is clicked the widget can change it's own position, but when I try to change the color nothing happens.
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()
誰能看出問題所在?
更新
仍然不確定這個問題的答案是什么,但我確實有一個解決方法:
Still not sure what the answer to this question is, but I do have a work around:
在 .kv 文件中,我將顏色指向對象中的一個變量.用于提取初始顏色:
In the .kv file I pointed the color to a variable in my object. Works for extracting the initial color:
Color:
rgba: self.col
當我想從 .py 文件中更改顏色時,我會遍歷畫布中的所有指令并修改顏色"類型的第一個指令.顯然這是一種 hack,并且不適用于具有多個 Color:
屬性的小部件:
When I want to change the color from the .py file I loop through all the instructions in the canvas and modify the first one of type "Color". Obviously this is a hack, and won't work on widgets with more than one Color:
property:
for i in s.canvas.get_group(None):
if type(i) is Color:
i.r, i.g, i.b, i.a = v
break
我將所有內容封裝在一個屬性中,這樣使用起來很整潔:
I wrapped that all up in a property so it's neat to use:
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
目前似乎可以使用.如果您知道更好的方法,請告訴我.我確信一定有一個更簡單的方法,而且我遺漏了一些明顯的東西!
Seems to work for now. Please let me know if you know a better way of doing this. I'm sure there must be a simpler way, and that I'm missing something obvious!
推薦答案
在您的初始版本中,您只是缺少屬性聲明
In your initial version, you were just missing the declaration of the property
from kivy.properties import NumericProperty
在標題和
r = NumericProperty(0)
就在class CircleWidget(Widget)下:
另外,您聲明您的 kv 文件名為 circletest.kv,但您的應用程序名為 TestApp,因此您應該更改其中一個以使其連貫,否則將找不到您的 kv 文件,但您不這樣做'不要報告任何問題,我想這只是問題中的錯字.剛剛看到 Builder.load_file
ok,
also, you state that your kv file is named circletest.kv, but your app is named TestApp, so you should change one of them to make them coherent, or your kv file won't be found, but as you don't report any issue with that, i guess it's only a typo in the question. edit: just saw the Builder.load_file
ok,
干杯.
這篇關于如何在運行時更改 Kivy 中小部件的顏色?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!