2017-12-31 196 views
1

このコードは、2つのKivyスライダを表示することを目的としています。第2のスライダは、第1のスライダと一緒に移動する必要があります(ただし反対ではありません)。kv言語でプロパティをバインドする方法は?

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() 

これは(kvlangで)私が見つけた唯一の解決策は次のとおりです。私は、バインディングが行われているクラスDoubleSliderをしました。しかし、私はそれを使用することはできません、示されているバインディングはサンプルです。

実際には、数値プロパティ(同じDoubleSliderオブジェクトの2番目のスライダではありません)を持つ他のオブジェクトでも最初のスライダの位置を使用できるようにしたいと思います。 <UI>ルールのだから私はラインvalue: slider_1.valueを削除して、このような<UI>ルール変更しようとした:

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

私も無駄にgetter('value')setter('value')を使用しようとしましたが。

質問

  • 私が逢引の用語で<UI>で何をしているのですか? (slider_2は財産ではなく、定期的に参照そのものであるので、私は何も結合していない恐れて、私はちょうど代わりslider_2プロパティを再割り当てしています)

  • <UI>にスライダーをバインドする適切な方法は何ですか?あなたがインスタンス化中綴じ変更したい場合は、それが最良の選択肢だかどうかは知りませんが、カスタムプロパティを使用することができ、

+0

あなたのコードはうまく見えますが、期待される効果があります(slider_1を変更するとslider_2も変更されますが、その逆もありません)。 – inclement

+0

@inclement:コードは機能しますが、インスタンスレベルでバインディングを行うという私の制約を満たしておらず、それに応じて編集しても機能しなくなります。 – mins

+0

私は、インスタンスレベルでバインディングを行うことで何を意味するのか分かりません。それが私があなたが実際にやったことです。 – inclement

答えて

1

(これは不可能でない限り、好ましくは、唯一のKV LANGを使用して)。また、これはあなたが欲しい時にアンバインドすることができます:

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


編集:別のオプションは、スライダーのvalueプロパティに関連付けられた新しいプロパティを作成することです

on_の構文を使用します。

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私は理解していると思う...別のアイデアがある、私のエディションを見てください。 – FJSevilla

+0

はい、可能な解決策です。私は、Pythonのslider_1.bind(value = slider_2.setter( 'value')) '(これはうまく機能しています)の厳密なkvlangに相当するものが存在するかどうか疑問に思っていました。しかし、おそらくあなたが提案しているのは、最も近いものです(あるいは*これは同等です)。 – mins

1

まず私は、バインディングが正しく

あなたは正しく結合やっ行われているかわかりません。これはkvlangを使うことでうまくいく:宣言的スタイルでプロパティをバインドすることができます。

KVファイルに結合:

value: slider_1.value 

と同じことを、純粋なPythonで:

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

は、だから私は唯一のインスタンスレベルでプロパティをバインドする必要があります。

あなたが実際にインスタンスレベルで物事を結合している:kvlangに<[email protected]>Sliderプロパティを設定するには - PythonでDoubleSliderインスタンスのコンストラクタ内のスライダー値をバインドと同じことです。

異なるDoubleSliderインスタンスの条件によって異なるバインディングが必要な場合は、それを行うためにPythonを使用することをお勧めします。

+0

確認していただきありがとうございます。 +1、私は私の質問を明らかにした。 – mins

関連する問題