Comment puis-je changer la couleur de mon widget dans Kivy au moment de l'exécution?
Je vais avoir du mal à changer la couleur d'un simple widget dans Kivy.
Je peux mettre la couleur quand j'ai créer le widget, mais je ne peux pas le changer par la suite.
Ici est la mise en page simple fichier de définition de circletest.kv
. Il définit un cercle où la couleur (en fait, juste le r, de rgba), la position et la taille sont tous liés à des variables dans la classe de widget.
#:kivy 1.4.1
<CircleWidget>:
canvas:
Color:
rgba: self.r,1,1,1
Ellipse:
pos: self.pos
size: self.size
Voici l'application circletest.py
. Il crée et affiche le widget simple. La couleur et la position sont correctement réglé lorsque l'objet est créé. Lorsque le widget est cliqué sur le widget peut changer sa propre position, mais lorsque je tente de changer la couleur ne se passe rien.
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()
Quelqu'un peut voir le problème?
Mise à JOUR
Toujours pas sûr de ce que la réponse à cette question est, mais j'ai un travail autour de:
Dans le .kv fichier j'ai fait la couleur d'une variable dans mon objet. Travaille pour l'extraction de la couleur initiale:
Color:
rgba: self.col
Lorsque je veux changer la couleur de la .py fichier je boucle sur toutes les instructions de la toile et de modifier le premier de type "Couleur". Évidemment, c'est un hack, et ne fonctionne pas sur les widgets avec plus d'un Color:
propriété:
for i in s.canvas.get_group(None):
if type(i) is Color:
i.r, i.g, i.b, i.a = v
break
J'ai enveloppé que les dans une propriété de sorte qu'il est soigné à utiliser:
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
Semble fonctionner pour l'instant. S'il vous plaît laissez-moi savoir si vous connaissez un meilleur moyen de le faire. Je suis sûr qu'il doit y avoir une façon plus simple, et que je suis absent quelque chose d'évident!
Salut @Difusio. Suggérez-vous, il pourrait être un type de conflit? Je suis sûr que r doit être une constante. J'ai juste essayé de réglage
s.r=0.0001
dans le constructeur, et je reçois un comportement similaire. J'ai essayé de réglage r pour une liste dans le constructeur s.r=[0.1]
et il a eu une erreur. Cependant quand je le faire ailleurs, dans la classe, il ne provoque pas d'erreur, ce qui suggère que s.r
n'est pas accessible par le cadre après que l'objet a été créé. Peut-être il ya certains appellent je peux faire pour forcer le cadre de la mise à jour des valeurs et de redessiner le widget?J'ai fait quelques expériences plus avec le type de ma couleur variable. Dans l' .kv fichier j'ai fait le rgba valeur à une variable unique
rgba: self.c
et puis initialisé comme une liste dans le constructeur self.c = [1,1,1,1]
. Cette présente exactement le même comportement: il définit la couleur sur la création, mais ne me permet pas de le régler par la suite. J'ai aussi essayé d'utiliser kivy de Color
classe: s.c = kivy.graphics.Color(1,1,1,1)
, mais qui m'a donné un type d'erreur car il ne supporte pas d'itération.OriginalL'auteur Andy | 2012-10-21
Vous devez vous connecter pour publier un commentaire.
Dans votre version initiale, vous étiez manque juste la déclaration de la propriété
dans l'en-tête et
juste sous
class CircleWidget(Widget):
aussi, vous dites que votre kv fichier est nommé circletest.kv, mais votre application est nommé TestApp, de sorte que vous devriez changer de l'un d'entre eux pour les rendre cohérents, ou votre kv fichier ne sera pas trouvé, mais que vous n'avez pas à signaler tout problème avec ça, je suppose que c'est seulement une faute de frappe dans la question. edit: viens de voir le
Builder.load_file
ok,acclamations.
Builder.load_file
etBuilder.load_string
mais il échoue lorsque le vertex instructions sont ajoutées dynamiquement (c'est à dire, avecwith self.canvas:
). J'ai créé une autre question here. Merci!J'ai ajouté un bounty... je suis dans le besoin de cette réponse depuis mon approche actuelle ne semble pas approprié. J'apprécierais vraiment si vous pouvez m'aider avec elle. Actuellement, je l'ai résolu le retrait et la création d'une nouvelle instance du sommet d'une instruction à chaque fois. Je ne comprends pas pourquoi il doit être nécessairement un nouvelle instance j'ai donc demandé à un autre la question ici.
OriginalL'auteur Tshirtman
La réponse par tshirtman est correct, voici l'explication de ce qui se passe.
Dans votre kv fichier lorsque vous définissez
La ligne
rgba: self.r, 1, 1, 1
tente de mettre à jour la valeur dergba
chaque fois qu'il y a un changement de la valeur der
. C'est fait de façon implicite dans kv de la langue par la liaison, ce qui peut être fait sur un kivy Propriété qu'il met en œuvre un Modèle Observateur.La variable
r
dans votre code a été mis à jour mais c'est juste une variable qui ne fournit pas une indication que la valeur a été modifiée et ne peut pas être lié à. Si vous remarquez que vos modificationspos
travail parce quepos
est un ReferenceListProperty.Règle générale pour la programmation en Kivy, si vous souhaitez modifier le code en fonction d'une propriété d'un Widget/Objet l'utilisation d'un Kivy Propriété. Il vous offre la possibilité d' Observer des modifications de la Propriété et ajustez votre code en conséquence, soit explicitement, par le biais de lier/on_property_name événements ou implicitement par kv de la langue comme mentionné ci-dessus.
OriginalL'auteur qua-non