I've setup a CheckBox in Kivy which, when ticked, adds a layout widget with some Labels and TextInputs but I want it to remove the layout when the box is unticked. Ticking the checkbox adds the layout with the right size and position (below the GridLayout with the CheckBox, within the input_layout
BoxLayout) but when I untick it, the layout doesn't go away. I've checked if it will remove the input_layout
layout, and it does, but not the one added through the python code.
The print statement prints False when the box is unticked so I know that it's working somewhat properly but the self.ids.input_layout.remove_widget(self.layout)
isn't removing the layout.
I tried setting up a template GridLayout to which the Labels and TextInputs would then be added through the CheckBox and python code. This setup partially worked; the Checkbox would add the widgets, and unticking it then removed them, but I couldn't add them back again as the whole GridLayout was gone.
The other CheckBoxes will add/remove different layouts so my first setup attempt is more ideal, if it can actually work.
Update:
Updated code with runnable example of the problem.
Python
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.metrics import dp
Builder.load_file("process_data_example_design.kv")
class ProcessDataEx(BoxLayout):
def add_layout(self, checkbox, value):
self.layout = GridLayout(cols=2, rows=4, size_hint_y=None, height=self.height*0.275, spacing=dp(8), padding=dp(8))
self.layout.add_widget(Label(text="Histogram particle label:", size_hint_x=None, width=self.width*0.33))
self.layout.add_widget(TextInput())
self.layout.add_widget(Label(text="Dumps to iterate:", size_hint_x=None, width=self.width*0.33))
self.layout.add_widget(TextInput())
self.layout.add_widget(Label(text="X-axis max:", size_hint_x=None, width=self.width*0.33))
self.layout.add_widget(TextInput())
self.layout.add_widget(Label(text="Y-axis max:", size_hint_x=None, width=self.width*0.33))
self.layout.add_widget(TextInput())
if value:
self.ids.input_layout.add_widget(self.layout)
else:
self.ids.input_layout.remove_widget(self.layout)
print(value)
class ProcessDataApp(App):
def build(self):
return ProcessDataEx()
if __name__ == '__main__':
ProcessDataApp().run()
Kivy
#:kivy 2.0.0
<ProcessDataEx>:
BoxLayout:
orientation: 'vertical'
BoxLayout:
id: input_layout
orientation: 'vertical'
GridLayout:
cols: 3
rows: 2
height: self.minimum_height
spacing: dp(8)
padding: dp(8)
Label:
text: 'Move data'
size_hint_y: None
height: self.texture_size[1]
halign: 'right'
Label:
text: 'Histograms'
size_hint_y: None
height: self.texture_size[1]
halign: 'right'
Label:
text: 'Log Histograms'
size_hint_y: None
height: self.texture_size[1]
halign: 'right'
CheckBox:
size_hint_y: None
height: root.height * 0.05
CheckBox:
size_hint_y: None
height: root.height * 0.05
CheckBox:
size_hint_y: None
height: root.height * 0.05
on_active: root.add_layout(*args)
the mistake you make is creating a new instance of laoyut
every time you call add_layout
method so the remomve widget did not work because the new widget it does not exists in the input_layout
the solution is to create the layout when is not exist so
your python code should be like this
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.metrics import dp
Builder.load_file("process_data_example_design.kv")
class ProcessDataEx(BoxLayout):
# initialize the layout variable
layout=None
def add_layout(self, checkbox, value):
if value:
self.layout = GridLayout(cols=2, rows=4, size_hint_y=None, height=self.height * 0.275, spacing=dp(8),
padding=dp(8))
self.layout.add_widget(Label(text="Histogram particle label:", size_hint_x=None, width=self.width * 0.33))
self.layout.add_widget(TextInput())
self.layout.add_widget(Label(text="Dumps to iterate:", size_hint_x=None, width=self.width * 0.33))
self.layout.add_widget(TextInput())
self.layout.add_widget(Label(text="X-axis max:", size_hint_x=None, width=self.width * 0.33))
self.layout.add_widget(TextInput())
self.layout.add_widget(Label(text="Y-axis max:", size_hint_x=None, width=self.width * 0.33))
self.layout.add_widget(TextInput())
self.ids.input_layout.add_widget(self.layout)
else:
self.ids.input_layout.remove_widget(self.layout)
print(value)
class ProcessDataApp(App):
def build(self):
return ProcessDataEx()
if __name__ == '__main__':
ProcessDataApp().run()