Reputation: 323
I have a simple user interface in kivy that consists of several gridlayouts inside of one large gridlayout.
The Code
This is the kv code for the interface
Builder.load_string('''
<GreyLabel>:
size_hint_y: None
height: 30
canvas.before:
Color:
rgba: .7, .7, .7, 1
Rectangle:
pos: self.pos
size: self.size
<ContainerBox>:
orientation: 'horizontal'
GridLayout:
cols: 1
row_force_default: True
foo: [self.rows_minimum.update({i: x.height}) for i, x in enumerate(reversed(list(self.children)))]
ResizingFrame:
id: Row1
cols: 1
GreyLabel:
text: "Something goes here"
GridLayout:
id: Row2
cols: 1
Label:
height: 30
text: 'Label One'
canvas.before:
Color:
rgba: .4, .4, .4, 1
Rectangle:
pos: self.pos
size: self.size
TextInput:
height: 30
multiline: False
write_tab: False
hint_text: 'Insert one liner'
GridLayout:
id: Row3
cols: 1
Label:
height: 45
text: 'Label two'
Button:
text: 'Button One'
height: 60
GridLayout:
rows: 1
height: 25
Button:
text: 'Button Two'
Button:
text: 'Button three'
''')
Notice the ResizingFrame
item. This is a GridLayout
class with the following code
class ResizingFrame(GridLayout):
c_value = StringProperty('SomeThing goes here')
def __init__(self, **kwargs):
super(ResizingFrame, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.adjustHeight(), 1)
def adjustHeight(self):
print("ResizingFrame.adjustHeight() before:", self.height)
self.height = 40
print("ResizingFrame.adjustHeight() after:", self.height)
You can find the entire code here.
The Goal
I want to be able to change the height of ResizingFrame
.
The interface starts out looking like this:
After 1 second, it should look like this: But it's not doing that.
Whenever adjustHeight()
runs, it says:
ResizingFrame.adjustHeight() before: 100
ResizingFrame.adjustHeight() after: 40
But this height change never actually happens for some reason. I simply can't change the height of ResizingFrame
. Why is this happening? And how can I fix it?
Note
This is related to this question.
I suspect the problem has something to do with the line:
foo: [self.rows_minimum.update({i: x.height}) for i, x in enumerate(reversed(list(self.children)))]
This should set the minimum height of the rows to the height of their children. But as you can see in screenshot 1, that's not happening. It just sets the minimum height to 100 and I can't change the height after that. I can't even increase the height above 100. It's just stuck.
Upvotes: 2
Views: 605
Reputation: 38837
The reason that you can't change the size of the ResizingFrame
, is that its size_hint
takes preference over any size changes. So, modifying your adjustHeight
method to:
def adjustHeight(self):
print("ResizingFrame.adjustHeight() before:", self.height)
self.size_hint_y = None
self.height = 40
print("ResizingFrame.adjustHeight() after:", self.height)
will allow the height
change to take effect.
Note that without setting size_hint_y
to None
, the you are changing the height
attribute, and that changed value is printed. But once your adjustHeight
method completes, then the ResizingFrame
height is recalculated and changed back to 100. You can see this by calling your original adjustHeight
method more than once (the before height
will always be bck to 100).
Upvotes: 3