I'm trying to make a class that would be a Slider + 2 Labels, one label showing the value of the slider, and one showing the name of the slider. The goal is to reuse this in lieu of Slider when convinient.
I am ending up creating properties in the my class MySlider reflecting the ones I am interested in in Slider. If, for example, I wanted to be able to also specify the color of the value label, I could do the same, add a property "value_label_color" to MySlider and set the label's color in on_value_label_color()... Then in the kv file I would do something like that:
value_label_color: 1,0,1,0.15
This would work but could be very long if I had many widgets in my MySlider class.
I thought there may be a way to avoid all this and directly access the label's color from the kv file, so I could do something like the following?
MySlider:
orientation: 'vertical'
id: slider2
name: 'hop'
step: 20
self.value_label.color: 1,1,1,0.15
But this doesn't work.
Here is my minimal code as of now: .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()
and the kv file:
#: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
If you have any suggestion about how to get there in the nicest (and economical) way, I would be grateful.
Thanks a lot. C
You can do that all from the kv
file. In fact, you don't even need to define the MySlider
class in the python code. You can modify your kv
like this:
#: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
and your python code simplifies to:
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()