0

Currently battling with Kivy nested layotus and scorll view. I dynamically add or remove from a table with some buttons. As the page grows I expect self.minimum_height of the parent CreatePly layout to change but it does not.

Is there a neat way to dynamically change the height of my scorll view or will I have to do it Caveman style and increase the it manually after the creation of every widget?

Python Code:

#This file contains the graphical user interface logic of the DIS creator from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.boxlayout import BoxLayout from kivy.metrics import dp from kivy.uix.widget import Widget from kivy.uix.button import Button from kivy.uix.label import Label from kivy.uix.textinput import TextInput from kivy.uix.togglebutton import ToggleButton class DIS3(App): pass class CreatePly(GridLayout): def __init__(self, **kwargs): super().__init__(**kwargs) #Dimensional control self.spacing = dp(2) self.padding = dp(10) self.cols = 1 self.size_hint = (1, None) self.height = self.minimum_height #I expect this to dynamically change with the nested layouts. It does not. #Varibales self.constituent_name = [] self.constituent_areaweight = [] self.structural_toggle = [] #Add and remove consituents #Header self.add_remove_header = BoxLayout() self.add_remove_header.size_hint = (1, None) self.add_remove_header.height = dp(40) label = Label(text="Add constituents to create a ply") self.add_remove_header.add_widget(label) self.add_widget(self.add_remove_header) #Add remove buttons self.add_remove_buttons = GridLayout() self.add_remove_buttons.cols = 4 self.add_remove_buttons.size_hint = (1, None) self.add_remove_buttons.height = dp(40) self.add_remove_buttons.add_widget(Widget()) button = Button(text="+", size_hint=(None, None), width=dp(40), height=dp(40)) button.bind(on_press = lambda x: self.add_constituent_press()) self.add_remove_buttons.add_widget(button) button = Button(text="-", size_hint=(None, None), width=dp(40), height=dp(40)) button.bind(on_press = lambda x: self.remove_constituent_press()) self.add_remove_buttons.add_widget(button) self.add_remove_buttons.add_widget(Widget()) self.add_widget(self.add_remove_buttons) #Constituent table self.constituent_table = GridLayout() self.constituent_table.cols = 3 label = Label(text="Consituent name", size_hint=(0.55, None), height=dp(20)) self.constituent_table.add_widget(label) label = Label(text="Areal weight (g/m2)", size_hint=(0.3, None), height=dp(20)) self.constituent_table.add_widget(label) label = Label(text="Structural?", size_hint=(0.15, None), height=dp(20)) self.constituent_table.add_widget(label) textinput = TextInput(size_hint=(0.55, None), height=dp(40)) self.constituent_name.append(textinput) self.constituent_table.add_widget(textinput) textinput = TextInput(size_hint=(0.3, None), height=dp(40)) self.constituent_areaweight.append(textinput) self.constituent_table.add_widget(textinput) toggle = ToggleButton(text="No", size_hint=(0.15, None), height=(dp(40))) toggle.bind(state=(lambda self, x: CreatePly.structural_constituent_toggle(self, toggle))) self.structural_toggle.append(toggle) self.constituent_table.add_widget(toggle) self.add_widget(self.constituent_table) #Build ply button self.footer = GridLayout() self.footer.cols = 3 self.footer.size_hint = (1, None) self.footer.height = dp(40) self.footer.add_widget(Widget()) button = Button(text="Create ply", size_hint=(None, None), width=dp(120), height=dp(40)) button.bind(on_press = lambda x: self.create_ply()) self.footer.add_widget(button) self.footer.add_widget(Widget()) self.add_widget(self.footer) #Functions def structural_constituent_toggle(self, toggle): if toggle.state == "normal": toggle.text = "No" else: toggle.text = "Yes" def add_constituent_press(self): textinput = TextInput(size_hint=(0.55, None), height=(dp(40))) self.constituent_name.append(textinput) self.constituent_table.add_widget(textinput) textinput = TextInput(size_hint=(0.3, None), height=(dp(40))) self.constituent_areaweight.append(textinput) self.constituent_table.add_widget(textinput) toggle = ToggleButton(text="No", size_hint=(0.15, None), height=(dp(40))) toggle.bind(state=(lambda self, x: CreatePly.structural_constituent_toggle(self, toggle))) self.structural_toggle.append(toggle) self.constituent_table.add_widget(toggle) def remove_constituent_press(self): if len(self.constituent_name) == 1: pass else: self.constituent_table.remove_widget(self.constituent_name[-1]) del self.constituent_name[-1] self.constituent_table.remove_widget(self.constituent_areaweight[-1]) del self.constituent_areaweight[-1] self.constituent_table.remove_widget(self.structural_toggle[-1]) del self.structural_toggle[-1] def create_ply(self): pass #Run loop DIS3().run() 

KV file code:

#This file contains the graphical user interface elements of the DIS creator app #This is the layout of the entire screen MainLayout: <MainLayout@BoxLayout>: #Background colour canvas.before: Color: rgba:(.3,.3,.3,1) Rectangle: pos: self.pos size: self.size padding: '10dp' spacing: '10dp' MenuLayout: FocusFrame: #This is the layout for the menu <MenuLayout@StackLayout>: #Background colour canvas.before: Color: rgba:(0,0,0,1) Rectangle: pos: self.pos size: self.size #Dimension control size_hint: None, 1 width: "160dp" spacing: "2dp" padding: "10dp" Button: text: "Database" size_hint: 1, None height: "40dp" Button: text: "Create ply" size_hint: 1, None height: "40dp" Button: text: "Create preform" size_hint: 1, None height: "40dp" Button: text: "Plan infusion" size_hint: 1, None height: "40dp" Button: text: "Write DIS" size_hint: 1, None height: "40dp" Button: text: "Review DIS" size_hint: 1, None height: "40dp" #This is the layout for the scrollable focus frame <FocusFrame@ScrollView>: canvas.before: Color: rgba:(0,0,0,1) Rectangle: pos: self.pos size: self.size CreatePly: 

Thanks in advance!

2 Answers 2

1

Using:

self.height = self.minimum_height 

in your __init__() method sets the height to the value of minimum_height at the time when the __init__() method executes. It will have no effect on the height after that.

You want to bind the minimum_height to the height, so that the height will change when minimum_height changes. Two ways to do that are to use:

height: self.minimum_height 

inside a kv file (The Builder will create the needed binding for you). or in your python code:

self.constituent_table.bind(minimum_height=self.constituent_table.setter('height')) 

which explicitly creates the needed binding. See the documentation.

So, try making the following changes to your code: In your kv file:

CreatePly: height: self.minimum_height 

and in your python code:

comment out the line in the __init__() method:

# self.height = self.minimum_height 

and add the lines:

 self.constituent_table.size_hint_y = None self.constituent_table.bind(minimum_height=self.constituent_table.setter('height')) 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your suggestion John. I've made the changes but the problem still persists. Did you test your suggested changes?
Yes, I did test the suggested changes. But in my post I forgot a required line to set size_hint_y to None. You must have size_hint as None in order for any changes in height to take effect. Sorry for my error. See my updated answer.
Great that has fixed it! Thank you very much John, Next I'm hoping to nest screens within the focus frame scrollview while maintaining the menu on the left. I see you have helped in a similar request before. Would you mind if I send you a private message regarding this kivy functionality?
You should just post another question showing your attempt at nesting screens.
0

This is my 'caveman' solution until I get an actual working automated scailing of the height:

I manually enter the desired starting height:

#self.height = self.minimum_height self.height = dp(220) 

I then add a cumulative height change within the add and remove functions:

self.height += dp(40) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.