如何用kv语言绑定属性?

问题描述 投票:1回答:2

此代码旨在显示两个kivy滑块。第二个滑块应与第一个滑块一起移动(但不是相反)。我有一个类DoubleSlider绑定完成:

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)

<DoubleSlider@BoxLayout>:
    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对象的第二个滑块),这意味着我将在<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>中绑定滑块的正确方法是什么? (最好只使用kv lang,除非这是不可能的)
python data-binding kivy
2个回答
1
投票

如果要在实例化期间修改绑定,我不知道它是否是最佳选项,但您可以使用自定义属性。这也可以让你在你想要的时候取消绑定:

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)

<DoubleSlider@BoxLayout>:
    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)

<DoubleSlider@BoxLayout>:
    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()

1
投票

首先,我不确定绑定是否正确完成

你已经正确绑定了。使用kvlang很酷:它允许以声明式样式绑定属性。

在kv文件中绑定:

value: slider_1.value

在纯Python中也是如此:

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

所以我只需要在实例级别绑定属性。

你实际上是绑定了实例级别的东西:在kvlang中设置Slider中的<DoubleSlider@BoxLayout>属性 - 与Python中DoubleSlider实例的构造函数中的绑定滑块值相同。

如果你需要不同的绑定取决于不同的DoubleSlider实例的条件,我担心你应该使用Python来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.