简体   繁体   中英

How to change size_hint dynamically in Kivy

I'm making a GUI with Kivy in Python.

I add a button dynamically with the code below.

recycleViewTest1.py

#-*- coding: utf-8 -*-
from kivy.config import Config
from kivy.uix.button import Button

Config.set('graphics', 'width', 300)
Config.set('graphics', 'height', 300)
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')  # eliminate annoying circle drawing on right click

from kivy.lang import Builder
Builder.load_string("""
<AddItemWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'

        RecycleView:
            size_hint: 1.0,1.0

            BoxLayout:
                id: box
                size_hint_y: 1.0
                orientation: 'vertical'

                Button:
                    size_hint_y: 1.0
                    id: addButton
                    text: "Add Item"
                    on_press: root.buttonClicked()
""")

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button

from kivy.properties import StringProperty


class AddItemWidget(Widget):
    def __init__(self, **kwargs):
        super(AddItemWidget, self).__init__(**kwargs)
        self.count = 0

    def buttonClicked(self):
        self.count += 1
        newButt = Button(text='Button'+ str(self.count),size_hint_y=1.0)
        self.ids.box.add_widget(newButt, index=1)
        self.ids.box.size_hint_y = 1.0 + 1.0 * self.count


class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)

    def build(self):
        return AddItemWidget()

if __name__ == '__main__':
    TestApp().run()

When actually executed recycleViewTest1.py, it will behave like the image below.

在此处输入图像描述

When I press the "Add Item" button, the button is dynamically added and size_hint_y is divided.

But I don't want to split size_hint_y.

I want to use RecycleView to make it scrollable once the button is added, as in the image below.I want to keep the button size unchanged.

在此处输入图像描述

I used recycleViewTest2.py to create the above image.

recycleViewTest2.py

#-*- coding: utf-8 -*-
from kivy.config import Config
from kivy.uix.button import Button

Config.set('graphics', 'width', 300)
Config.set('graphics', 'height', 300)
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')  # eliminate annoying circle drawing on right click

from kivy.lang import Builder
Builder.load_string("""
<AddItemWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'

        RecycleView:
            size_hint: 1.0,1.0

            BoxLayout:
                id: box
                size_hint_y: 2.0
                orientation: 'vertical'

                Button:
                    size_hint_y: 1.0
                    text: "Button1"

                Button:
                    size_hint_y: 1.0
                    id: addButton
                    text: "Add Item"
                    on_press: root.buttonClicked()
""")

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button

from kivy.properties import StringProperty


class AddItemWidget(Widget):
    def __init__(self, **kwargs):
        super(AddItemWidget, self).__init__(**kwargs)
        self.count = 0

    def buttonClicked(self):
        self.count += 1
        newButt = Button(text='Button'+ str(self.count),size_hint_y=1.0)
        self.ids.box.add_widget(newButt, index=1)


class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)

    def build(self):
        return AddItemWidget()

if __name__ == '__main__':
    TestApp().run()

The recycleViewTest2.py is close to ideal, but I want to add an element that keeps the size of the button fixed when the Add Item button is pressed.

When I press the Add Item button in recycleViewTest2.py, the button size is reduced.

How do I fix the button size while making the recycleViewTest1.py work like the recycleViewTest2.py?

I wrote the recycleViewTest3.py.

recycleViewTest3.py

#-*- coding: utf-8 -*-
from kivy.config import Config
from kivy.uix.button import Button

Config.set('graphics', 'width', 300)
Config.set('graphics', 'height', 300)
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')  # eliminate annoying circle drawing on right click

from kivy.lang import Builder
Builder.load_string("""
<AddItemWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'

        RecycleView:
            size_hint: 1.0,1.0

            BoxLayout:
                id: box
                size_hint_y: 1.01
                orientation: 'vertical'

                Button:
                    size_hint_y: 0.5
                    text: "Button1"

                Button:
                    size_hint_y: 0.5
                    id: addButton
                    text: "Add Item"
                    on_press: root.buttonClicked()

                Label:
                    size_hint_y: 0.01
                    text: ""
""")

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button

from kivy.properties import StringProperty


class AddItemWidget(Widget):
    def __init__(self, **kwargs):
        super(AddItemWidget, self).__init__(**kwargs)
        self.count = 0

    def buttonClicked(self):
        self.count += 1
        self.ids.box.size_hint_y = self.ids.box.size_hint_y + 0.5
        newButt = Button(text='Button'+ str(self.count),size_hint_y=0.5)
        self.ids.box.add_widget(newButt, index=1)


class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)

    def build(self):
        return AddItemWidget()

if __name__ == '__main__':
    TestApp().run()

The recycleViewTest3.py will increase the size_hint_y of the boxLayout by the amount of buttons added, which is what it should look like.

However, immediately after pressing the Add Item button, the size of the button goes out of whack. Scrolling the mouse will fix the button size.

在此处输入图像描述

I would like to know if there is a way to add a button like this and immediately update the size_hint_y.

To keep the buttons from automagically changing size, you have to provide them with one, manually.

Builder.load_string("""
<AddItemWidget>:
    BoxLayout:
        size: root.size
        orientation: 'vertical'

        RecycleView:
            size_hint: 1.0,1.0

            BoxLayout:
                id: box
                size_hint_y: None
                height: self.minimum_height  # use this to keep its size relative to its children
                orientation: 'vertical'

                Widget:  # bonus: use this to keep the buttons to the bottom
                    size_hint_y: None
                    height: root.height - ((len(box.children) - 1) * dp(60))

                Button:
                    text: "Button0"
                    size_hint_y: None
                    height: dp(60)

                Button:
                    size_hint_y: None
                    height: dp(60)
                    id: addButton
                    text: "Add Item"
                    on_press: root.buttonClicked()
""")


class AddItemWidget(Widget):
    def __init__(self, **kwargs):
        super(AddItemWidget, self).__init__(**kwargs)
        self.count = 0

    def buttonClicked(self):
        self.count += 1
        newButt = Button(text='Button'+ str(self.count),size_hint_y=None, height=dp(60))
        self.ids.box.add_widget(newButt, index=1)


class TestApp(App):
    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)

    def build(self):
        return AddItemWidget()

if __name__ == '__main__':
    TestApp().run()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM