2016-04-29 24 views
1

Manchmal ist ObjectProperty nicht geeignet. Dies liegt daran, dass nur ein Ereignis ausgelöst wird, wenn sich der Wert des Objekts ändert.Gibt es eine Möglichkeit, benutzerdefinierte Eigenschaften in Kivy zu erstellen?

Aber was ist, wenn sich ein Attribut des Objekts ändert? Ein Ereignis wird nicht ausgelöst.

Betrachten wir eine Klasse:

class Point(object): 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

Und ein Kivy widget:

class MyWidget(Widget): 
    point = ObjectProperty() 

    def __init__(self, point): 
     super(MyWidget, self).__init__() 
     self.point = point 

    def on_point(self, obj, value): 
     # do something 

Was passiert, wenn ich etwas über point ändern?

w = MyWidget(Point(0, 0)) 
w.point.x = 10 
# callback not called! 

Der Rückruf wurde nicht, weil so weit genannt wie ObjectProperty betrifft, point nicht geändert hat. Aber ich möchte Änderungen an x und y als Änderungen gezählt werden und ein Ereignis auslösen.

Ähnlich wie ListProperty weiß, ein Ereignis auszulösen, wenn sich die Länge der Liste ändert.

Dafür denke ich, ich muss eine Property Unterklasse PointProperty erstellen.

Aber ich habe keine Dokumentation gefunden, wie man das macht. Hilfe wäre willkommen.

Antwort

0

Sie müssen dafür keinen neuen Eigenschaftstyp erstellen; baue große Dinge aus kleinen Dingen. Machen Sie diese x und y numerischen Eigenschaften.

class Point(EventDispatcher): 

    x = NumericProperty(0) 
    y = NumericProperty(0) 

    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    def on_x(self, obj, value): 
     print 'x changed:', value 

    def on_y(self, obj, value): 
     print 'y changed:', value 

Dann

w = MyWidget(Point(0, 0)) 
w.point.x = 10 
# 'x changed: 10' 
+0

Nette Idee, aber das ist noch nicht perfekt. Was passiert, wenn ich Kurse von Drittanbietern nutze, die nicht mit Kivy zu tun haben? Außerdem benutze ich Kivys "Vector" -Klasse, die nicht auf diese Weise aufgebaut ist (das hat mich zu dieser Frage geführt). –

+0

@zeeMonkeez Danke, dass Sie darauf hingewiesen haben. – jligeza

+0

@AvivCohn Es ist sinnlos, Änderungen am * gesamten * Objekt zu verfolgen, da dies eine Menge unnötiger Berechnungen zur Folge hätte, die Ihre Anwendung verlangsamen würden. Ich weiß nicht, was genau Sie versuchen, indem Sie versuchen, alle Felder auf einem externen Klassenobjekt zu verfolgen; aber wie auch immer, du könntest es einfach einpacken. – jligeza