Kivy:制作包含不同小部件并能够在 kv 文件中访问其属性的单个小部件的最佳方法

Kivy: best way to make a single widget containing different widgets and being able to access their properties in the kv file

我正在尝试制作一个 class,它将是一个滑块 + 2 个标签,一个标签显示滑块的值,一个标签显示滑块的名称。目标是在方便时重用它代替 Slider。

我最终将在我的 class MySlider 中创建属性,以反映我对 Slider 感兴趣的属性。 例如,如果我还希望能够指定值标签的颜色,我可以这样做,将 属性 "value_label_color" 添加到 MySlider 并在 on_[ 中设置标签的颜色=32=]()... 然后在 kv 文件中我会做类似的事情:

value_label_color: 1,0,1,0.15

这可行,但如果我的 MySlider 中有很多小部件,则可能会很长 class。

我认为可能有一种方法可以避免这一切并直接从 kv 文件中访问标签的颜色,所以我可以执行以下操作?

    MySlider:
        orientation: 'vertical'
        id: slider2
        name: 'hop'
        step: 20
        self.value_label.color: 1,1,1,0.15

但这行不通。

这是我目前的最少代码: .py:

from kivy.config import Config
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.slider import Slider
from kivy.app import App
from kivy.properties import NumericProperty, StringProperty


class MySlider(BoxLayout):
    name = StringProperty('Param')
    min = NumericProperty(0)
    max = NumericProperty(100)
    step = NumericProperty()

    def __init__(self, *args, **kwargs):
        super(MySlider, self).__init__(*args, **kwargs)

        self.value_label = Label()
        self.value_label.id = "value_label"
        self.slider = Slider()
        self.slider.bind(value=self._on_value)
        self.name_label = Label()

        self.value_label.text = str(self.slider.value)
        self.slider.orientation = 'vertical'

        self.add_widget(self.value_label)
        self.add_widget(self.slider)
        self.add_widget(self.name_label)

    def on_name(self, obj, val):
        self.name_label.text = val

    def on_min(self, obj, val):
        self.slider.min = val

    def on_max(self, obj, val):
        self.slider.max = val

    def on_step(self, obj, val):
        self.slider.step = val

    def _on_value(self, obj, val):
        self.value_label.text = str(self.slider.value)


class MyLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(MyLayout, self).__init__(**kwargs)


class test7App(App):
    def build_config(self, config):
        Config.set('kivy', 'exit_on_escape', '0')
        Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
        self.title = 'My Sliders'

    def build(self):
        return MyLayout()


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

和 kv 文件:

#:kivy 2.0.0


<MyLayout>:
    orientation : 'horizontal'

    canvas:
        Color:
            rgba: 1,1,1,0.15
        Rectangle:
            size: self.size
            pos: self.pos

    MySlider:
        orientation: 'vertical'
        id: slider1
        name: "hip"
        min: -30
        max: +60
        step: 1

    MySlider:
        orientation: 'vertical'
        id: slider2
        name: 'hop'
        step: 20

如果您对如何以最好(和最经济)的方式到达那里有任何建议,我将不胜感激。

非常感谢。 C

您可以从 kv 文件中完成所有操作。事实上,您甚至不需要在 python 代码中定义 MySlider class。您可以这样修改 kv

#:kivy 2.0.0

<MySlider@BoxLayout>:
    orientation: 'vertical'
    name: 'Param'
    min: 0
    max: 100
    step: 1
    value_label_color: 1,1,1,0.15
    
    Label:
        id: value_label
        text: str(slider.value)
        color: root.value_label_color
    Slider:
        id: slider
        orientation: root.orientation
        min: root.min
        max: root.max
        step: root.step
    Label:
        text: root.name
    


<MyLayout>:
    orientation : 'horizontal'

    canvas:
        Color:
            rgba: 1,1,1,0.15
        Rectangle:
            size: self.size
            pos: self.pos

    MySlider:
        orientation: 'vertical'
        id: slider1
        name: "hip"
        min: -30
        max: +60
        step: 1

    MySlider:
        orientation: 'horizontal'
        id: slider2
        name: 'hop'
        step: 20

并且您的 python 代码简化为:

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


class MyLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(MyLayout, self).__init__(**kwargs)


class test7App(App):
    def build_config(self, config):
        Config.set('kivy', 'exit_on_escape', '0')
        Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
        self.title = 'My Sliders'


    def build(self):
        return MyLayout()


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