简体   繁体   中英

How to adjust the size of current widget class when its size based on another widget class in Kivy

I am having too many types of buttons in my project, the problem is they all have different sizes. So I decided to create a BaseButtonSize class and then apply its size to the rest. If I want to change the button size, I just simply take the BaseButtonSize.width (or .height) and multiply it with a specific number (you can see it in the code in KButton2 class).

But it doesn't seem to be working. And the traceback returned 5292 lines .-.

So is there any way to fix or better way to do that? When you can adjust the size of the current widget that you taken from another class.

from kivy.uix.button import Button
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.boxlayout import BoxLayout

from kivy.lang import Builder


Builder.load_string("""
#:import Window kivy.core.window.Window

<ViewPort>:
    KButton1:
    KButton2:

<BaseButtonSize>:
    size_hint: None,None
    size: Window.width*0.0441,Window.height*0.147

<KButton1>:
    size_hint: None,None
    size: button.size
    
    BaseButtonSize:
        id: button

<KButton2>:
    size_hint: None,None
    size: button.size
    
    BaseButtonSize:
        id: button
        width: self.width*1.25 # <<<<===== Can not adjust the width (Remove this line will work fine)
""")

class BaseButtonSize(Button):
    pass

class KButton1(RelativeLayout):
    pass

class KButton2(RelativeLayout):
    pass

class ViewPort(BoxLayout):
    pass

if __name__=="__main__":
    from kivy.app import App
    class TestApp(App):
        def build(self):
            return ViewPort()
    
    TestApp().run()

Using width: self.width*1.25 creates an infinite loop. A width is assigned to BaseButtonSize , then it is adjusted to 1.25 times the width , which changes the width and triggers the above kv rule, which adjusted the width by again multiplying it by 1.25, which triggers the above rule again, ...

You can avoid this infinite loop by using:

width: Window.width*0.0441*1.25

Or, you can set a key in your kv , like this:

#:set w Window.width*0.0441

Then use that elsewhere in the kv :

<BaseButtonSize>:
    size_hint: None,None
    size: w,Window.height*0.147

and:

BaseButtonSize:
    id: button
    width: w*1.25

Both of these approaches eliminate the infinite loop.

Yet another approach (that I think solves all your issues) is to just set a key to the 0.0441 value, and use that elsewhere in your kv . And set the size in the KButton class, allowing the default size_hint of BaseButton to adjust its size. Here is a modified version of your code that does this:

from kivy.uix.button import Button
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.boxlayout import BoxLayout

from kivy.lang import Builder

Builder.load_string("""
#:import Window kivy.core.window.Window
#: set w_factor 0.0441

<ViewPort>:
    KButton:
        text: '1'
    KButton:
        text: '2'
        width_factor: 1.25

<KButton>:
    width_factor: 1
    size_hint: None,None
    size: Window.width * self.width_factor * w_factor, Window.height*0.147
    text: ''

    BaseButtonSize:
        text: root.text
""")


class BaseButtonSize(Button):
    pass


class KButton(RelativeLayout):
    pass


class ViewPort(BoxLayout):
    pass


if __name__ == "__main__":
    from kivy.app import App


    class TestApp(App):
        def build(self):
            return ViewPort()


    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