简体   繁体   English

如何在 Kivy 中动态更改 size_hint

[英]How to change size_hint dynamically in Kivy

I'm making a GUI with Kivy in Python.我正在使用 Python 中的 Kivy 制作 GUI。

I add a button dynamically with the code below.我使用下面的代码动态添加了一个按钮。

recycleViewTest1.py 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.当实际执行 recycleViewTest1.py 时,它的行为如下图所示。

在此处输入图像描述

When I press the "Add Item" button, the button is dynamically added and size_hint_y is divided.当我按下“添加项目”按钮时,按钮被动态添加,size_hint_y被分割。

But I don't want to split size_hint_y.但我不想拆分 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.添加按钮后,我想使用 RecycleView 使其可滚动,如下图所示。我想保持按钮大小不变。

在此处输入图像描述

I used recycleViewTest2.py to create the above image.我使用 recycleViewTest2.py 创建了上面的图像。

recycleViewTest2.py 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. recycleViewTest2.py 接近理想状态,但我想添加一个元素,在按下“添加项目”按钮时保持按钮大小不变。

When I press the Add Item button in recycleViewTest2.py, the button size is reduced.当我按下 recycleViewTest2.py 中的 Add Item 按钮时,按钮大小会减小。

How do I fix the button size while making the recycleViewTest1.py work like the recycleViewTest2.py?如何在使 recycleViewTest1.py 像 recycleViewTest2.py 一样工作时修复按钮大小?

I wrote the recycleViewTest3.py.我写了recycleViewTest3.py。

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. recycleViewTest3.py 将 boxLayout 的 size_hint_y 增加按钮的数量,这应该是它的样子。

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.我想知道是否有办法添加这样的按钮并立即更新 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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