I want to create a control panel which provides a slider for quick input but also an textinput to type in the exact value as float number. Additionally there shall be a label, which displays the actual value. The problem is, that I am not quit shure how to link all three widgets to each other AND auto update them if one changes the value... Everything is done in an external .kv file.
Here is my first attempt via id. It works but the textinput does not change its content if I change the sliders value. Does anyone have a better solution for my problem? Thanks for your help :)
That's the content of test.kv:
<MainLayout>:
BoxLayout:
pos: self.parent.x + self.parent.width*0.1, self.parent.y
orientation: 'vertical'
BoxLayout:
orientation: 'horizontal'
Label:
color: 0, 0, 0, 1
font_size: 20
text: 'Position: ' + str(linear_pos_slider.value) + ' mm'
size: self.texture_size
Slider:
id: linear_pos_slider
orientation: 'horizontal'
max: 50
min: -50
padding: 1
value: float(linear_pos_ti.text)
step: 0.1
TextInput:
id: linear_pos_ti
size_hint: 0.2, 0.8
font_size: 20
text_color: 0, 0, 0, 1
input_filter: 'float'
multiline: 'False'
text: '0'
And here is the content of the test.py to make the application run:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.slider import Slider
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
Window.clearcolor = (1, 1, 1, 1)
class MainLayout(BoxLayout):
pass
class Test(App):
def build(self):
return MainLayout()
if __name__ == "__main__":
Test().run()
You should just be able to bind them to each other:
Label:
color: 0, 0, 0, 1
font_size: 20
text: 'Position: ' + str(linear_pos_slider.value) + ' mm'
size: self.texture_size
Slider:
id: linear_pos_slider
orientation: 'horizontal'
max: 50
min: -50
padding: 1
value: float(linear_pos_ti.text)
step: 0.1
TextInput:
id: linear_pos_ti
size_hint: 0.2, 0.8
font_size: 20
text_color: 0, 0, 0, 1
input_filter: 'float'
multiline: 'False'
text: str(linear_pos_slider.value)
Although in practice, it would be better if you used a NumericProperty (or StringProperty) in the code and bound them to that. This has all the same advantages but it is cleaner and gives you easy access from the code side too.
Note that since the bindings are one-way (property -> widget), you will need to set it with on_*
events:
Slider:
id: linear_pos_slider
orientation: 'horizontal'
max: 50
min: -50
padding: 1
value: root.value
on_value: root.value = self.value
step: 0.1
TextInput:
id: linear_pos_ti
size_hint: 0.2, 0.8
font_size: 20
text_color: 0, 0, 0, 1
input_filter: 'float'
multiline: 'False'
text: str(root.value)
on_text: root.value = float(self.text)
with:
from kivy.properties import NumericProperty, StringProperty
class MainLayout(BoxLayout):
value = NumericProperty(0.0)
pass