2017-12-31 101 views
1

Dieser Code soll zwei kivy Schieberegler anzeigen. Der zweite Schieberegler sollte sich mit dem ersten Schieberegler bewegen (aber nicht umgekehrt). Ich habe eine Klasse DoubleSlider wo die Bindung erfolgt:Wie bind Eigenschaften in kv Sprache?

import kivy 
from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.boxlayout import BoxLayout 

kivy.require('1.10.0') 

Builder.load_string (""" 
<Slider> 
    size_hint: 1, None 
    height: dp(40) 

<[email protected]>: 
    slider_1: slider_1 
    slider_2: slider_2 
    orientation: 'vertical' 

    Slider 
     id: slider_1 

    Slider 
     id: slider_2 
     value: slider_1.value 

<UI>: 
    orientation: 'vertical' 
    DoubleSlider:   
""") 


class UI(BoxLayout): 
    pass 


class MyApp(App): 
    def build(self): 
     return UI() 


if __name__ == '__main__': 
    MyApp().run() 

Dies ist die einzige Lösung, die ich (in kvlang) gefunden habe. Allerdings kann ich es nicht verwenden, die abgebildete Bindung ist nur eine Probe.

Eigentlich möchte ich in der Lage sein, die Position des ersten Sliders in anderen Objekten zu verwenden, die eine numerische Eigenschaft haben (nicht speziell der zweite Slider des gleichen DoubleSlider Objekts), was bedeutet, dass ich die Bindung von Fall zu Fall mache in der <UI> Regel. So entferne ich die Linie value: slider_1.value und versuchte, die <UI> Regel wie folgt zu ändern:

<UI>: 
    DoubleSlider: 
     # Is expected to be equivalent, but doesn't work 
     slider_2.value: slider_1.value 

ich auch habe versucht getter('value') und setter('value') ohne Erfolg zu nutzen.

Fragen:

  • Was ich in <UI> in der Bezeichnung der assignation mache? (Ich fürchte, ich nichts binden, aber ich bin Neuzuweisung nur slider_2 Eigenschaft statt, weil slider_2 selbst eine Eigenschaft, keine reguläre Referenz)

  • Was ist der richtige Weg, um die Schieber in <UI> zu binden? (Mit vorzugsweise nur kv lang, sofern dies nicht unmöglich ist)

+0

Ihr Code scheint in Ordnung und hat den erwarteten Effekt (das Ändern von slider_1 ändert auch slider_2, aber nicht umgekehrt). – inclement

+0

@inclement: Der Code funktioniert, aber erfüllt nicht meine Einschränkung der Bindung auf Instanzebene, und wenn sie entsprechend bearbeitet wird, funktioniert nicht mehr. – mins

+0

Ich weiß nicht, was Sie meinen, indem Sie die Bindung auf Instanzenebene durchführen. Das würde ich als das bezeichnen, was Sie tatsächlich getan haben. – inclement

Antwort

1

Wenn Sie während der Instanziierung Bindung ändern wollen, ich weiß nicht, ob es die beste Option ist, aber Sie können eine benutzerdefinierte Eigenschaft verwenden. Dies ermöglicht es Ihnen auch entbinden, wenn Sie wollen:

import kivy 
from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.boxlayout import BoxLayout 

kivy.require('1.10.0') 

Builder.load_string (""" 
<Slider> 
    size_hint: 1, None 
    height: dp(40) 

<[email protected]>: 
    tied: False     # <<<<<<<<<< 
    slider_1: slider_1 
    slider_2: slider_2 
    orientation: 'vertical' 

    Slider 
     id: slider_1 

    Slider 
     id: slider_2 
     value: slider_1.value if root.tied else self.value 


<UI>: 
    orientation: 'vertical' 
    BoxLayout: 
     Label: 
      text: "Tied" 
     CheckBox: 
      on_active: ds.tied = not ds.tied 

    DoubleSlider:  
     id: ds 
""") 


class UI(BoxLayout): 
    pass 


class MyApp(App): 
    def build(self): 
     return UI() 


if __name__ == '__main__': 
    MyApp().run() 

enter image description here


Edit:

Eine weitere Option ist eine neue Eigenschaft, die mit der value Eigenschaft des Schiebers zu erstellen und verwenden Sie die on_ Syntax:

import kivy 
from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.boxlayout import BoxLayout 

kivy.require('1.10.0') 

Builder.load_string (""" 
<Slider> 
    size_hint: 1, None 
    height: dp(40) 

<[email protected]>: 
    slider_1: slider_1 
    slider_2: slider_2 
    value1: slider_1.value 
    value2: slider_2.value 
    orientation: 'vertical' 

    Slider 
     id: slider_1 

    Slider 
     id: slider_2 



<UI>: 
    orientation: 'vertical' 

    DoubleSlider: 
     on_value1: self.slider_2.value = self.value1 

""") 


class UI(BoxLayout): 
    pass 


class MyApp(App): 
    def build(self): 
     return UI() 


if __name__ == '__main__': 
    MyApp().run() 
+0

@mins Ich denke, ich habe verstanden ... Ich habe eine andere Idee, schau dir meine Ausgabe an. – FJSevilla

+0

Ja, das ist eine mögliche Lösung. Ich habe mich gefragt, ob ein strenges kvlang-Äquivalent von Python 'slider_1.bind (value = slider_2.setter ('value'))' (was funktioniert) existiert. Aber vielleicht ist das, was Sie vorschlagen, das nächste (oder sogar * ist * das Äquivalent). – mins

1

Zuerst bin ich nicht sicher, ob die Bindung richtig

erfolgt Du hast Bindung richtig gemacht. Es ist cool, kvlang zu verwenden: Es erlaubt, Eigenschaften im deklarativen Stil zu binden.

Bindung in kv-Datei:

value: slider_1.value 

Und elbe in reinem Python:

slider_1.bind(value=slider_2.setter('value')) 

Also muß ich nur die Eigenschaften auf Instanzebene binden.

Sie sind eigentlich Dinge auf Instanzebene Bindung: Slider Eigenschaften innen <[email protected]> in kvlang Einstellung - ist elbe wie Bindeschieber Werte innerhalb DoubleSlider Instanz Konstruktor in Python.

Wenn Sie abhängig von den Bedingungen für verschiedene DoubleSlider Instanzen unterschiedliche Bindungen benötigen, sollten Sie Python dafür verwenden.

+0

Danke für die Bestätigung. +1, und ich habe meine Frage geklärt. – mins

Verwandte Themen