Reputation: 586
I have written a Kivy GUI that consists of various buttons and nested layouts. I want to be able to, on a click of a button, append a section of code n number of times within one of these layouts, specifically the scroll layout. Since I have am very new to Kivy and since I cannot seem to find a tutorial on this matter, I am presenting it here.
Here is the Python code:
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget
class Interface(Widget):
pass
class GUI(App):
def build(self):
return Interface()
if __name__ == "__main__":
GUI().run()
And the total Kivy code:
<Interface>:
GridLayout:
padding:0
size: root.width, root.height
cols:1
#Top buttons
GridLayout:
size_hint: 1, 0.07
padding:0
cols:1
Button:
text:"Add Phase"
#Chart areas
ScrollView:
do_scroll_y:False
BoxLayout:
orientation: "vertical"
size_hint_x: None
width: self.minimum_width
GridLayout:
size_hint_x: None
width: self.minimum_width
cols:20
#Phase template
GridLayout:
width: 200
size_hint_x: None
cols:1
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Phase"
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Step"
Button:
size_hint:1, 0.07
text:"Add Step"
GridLayout:
cols:20
#Step template
GridLayout:
width: 100
size_hint_x: None
cols:1
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Var1"
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Var2"
Button:
background_normal: ''
background_color: 0.28,0.59,0.72,1
text:"Test"
Button:
size_hint:1, 0.07
text:"Delete"
Button:
background_color: 0.8,0,0,1
size_hint:1, 0.07
text:"Delete"
You will see in the Kivy code that these is a commented secion called #Phase template
. Basically on pressing the button Add Phase
, this entire section and its children elements should be appended in the immediate parent GridLayout
.
Here you can press the Add Phase button:
Which will result in this:
And then finally, pressing the Delete
button should remove that specific appended section of code.
Again, no idea how to approach this from the Kivy language, which seems a bit rigid to work with. But I am sure what I want to do can be accomplished.
Upvotes: 0
Views: 103
Reputation: 39052
One way to accomplish that is to create a Phase
class, and add a kv
rule for building instances of Phase
. Then, in kv
, you can use Factory.Phase()
to create new instances.
Modify your kv
as:
#:import Factory kivy.factory.Factory
<Interface>:
GridLayout:
padding:0
size: root.width, root.height
cols:1
#Top buttons
GridLayout:
size_hint: 1, 0.07
padding:0
cols:1
Button:
text:"Add Phase"
on_release: grid.add_widget(Factory.Phase()) # this adds another Phase
#Chart areas
ScrollView:
do_scroll_y:False
BoxLayout:
orientation: "vertical"
size_hint_x: None
width: self.minimum_width
GridLayout:
id: grid # added id to identify where to add new Phase instances
size_hint_x: None
width: self.minimum_width
cols:20
# initial Phase instance
Phase:
#Phase template
<Phase@GridLayout>:
width: 200
size_hint_x: None
cols:1
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Phase"
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Step"
Button:
size_hint:1, 0.07
text:"Add Step"
GridLayout:
cols:20
#Step template
GridLayout:
width: 100
size_hint_x: None
cols:1
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Var1"
TextInput:
size_hint: 1, 0.06
halign: 'center'
hint_text:"Var2"
Button:
background_normal: ''
background_color: 0.28,0.59,0.72,1
text:"Test"
Button:
size_hint:1, 0.07
text:"Delete"
Button:
background_color: 0.8,0,0,1
size_hint:1, 0.07
text:"Delete"
on_release: root.parent.remove_widget(root) # delete this Phase
Key points are the <Phase@GridLayout>
rule, the new grid
id
, and the use of Factory
in the Add Phase
Button.
Upvotes: 1