I'm trying to implement a feature that would change spinner values (dropdown items) depending on which button was previously pressed. But for some reason, any attempt to write if statement directly in kv file results in just the latest list being selected for the values.
Some context - pressing one of three client buttons adds a value in the 'collected_info' dictionary 'Client' key. Then, ideally, Spinner widget should check what's the value in that key, and change it's (Spinner's) value property accordingly.
Here's python code:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import BooleanProperty
from kivy.uix.popup import Popup
from kivy.core.window import Window
from kivy.uix.recycleview import RecycleView
from kivy.lang import Builder
from kivy.uix.widget import Widget
class ProtocolInfoPage(Screen):
collected_info = {'Client': '', 'Work': '', 'Object': '',
'Pilot Drill': '', 'Extender': '', 'Reamer': '',
'Liners': {'4x20': [], '8x10': []}, 'Caula/Casing': ''}
mup = ['1','2','3','4','5']
olaf = ['6','7','8','9']
fnb = ['10','10','10','10']
def collect_info(self):
self.collected_info['Pilot Drill'] = self.ids.pilot.text
self.collected_info['Extender'] = self.ids.extender.text
self.collected_info['Reamer'] = self.ids.reamer.text
self.collected_info['Caula/Casing'] = self.ids.caula.text
kv = Builder.load_file("test.kv")
class MyApp(App):
def build(self):
return ProtocolInfoPage()
if __name__ == '__main__':
MyApp().run()
And here's kv file:
<ProtocolInfoPage>:
BoxLayout:
orientation: 'vertical'
GridLayout:
cols:3
size: 50,50
ToggleButton:
group: 'client'
text: 'MUP'
on_press: root.collected_info['Client'] = 'MUP'
ToggleButton:
group: 'client'
text: 'Olaf Sitte'
on_press: root.collected_info['Client'] = 'Olaf Sitte'
ToggleButton:
group: 'client'
text: 'FNB'
on_press: root.collected_info['Client'] = 'FNB'
Spinner:
id: object_dropdown
size_hint: 1, None
text: 'Choose Object'
height: 44
sync_height: True
values: root.olaf
on_text:
root.collected_info['Object'] = object_dropdown.text
I understand that it might be easier and better to do such tasks in the python code itself, but I'm slightly confused with the way widgets declared in python are inserted in already written kv layout with other widgets.
Any help would be greatly appreciated!
One of the few ways you can achieve that as follows,
First define a method in your class ProtocolInfoPage
say, update_collected_info
as,
def update_collected_info(self, text):
self.collected_info['Client'] = text
# Access the dropdown.
dropdown = self.ids.object_dropdown
# Now map separately or use a predefined dictionary for efficient access.
if text == "MUP":
dropdown.values = self.mup
elif text == "Olaf Sitte":
dropdown.values = self.olaf
elif text == "FNB":
dropdown.values = self.fnb
print(self.collected_info)
Now from each button in your kvlang
pass the arg 'text' to this method as,
...
GridLayout:
cols:3
size: 50,50
ToggleButton:
group: 'client'
text: 'MUP'
# Assuming the value for the key "Client" will always be its text.
# If necessary change and pass something you need.
on_press: root.update_collected_info(self.text)
ToggleButton:
group: 'client'
text: 'Olaf Sitte'
on_press: root.update_collected_info(self.text)
ToggleButton:
group: 'client'
text: 'FNB'
on_press: root.update_collected_info(self.text)
Spinner:
id: object_dropdown
...