Home > Blockchain >  how I will Change the font size of the text of kivy button dynamically in .py file
how I will Change the font size of the text of kivy button dynamically in .py file

Time:04-24

Actually I want to try to Change my kivy Button's font_Size dynamically Accoding to the Width of its Parnet Widget. so I can make it resizable according to the Screen of Kivy Gui App I am want to Change it in .py file as a code (without the use of .kv file or kv string) I am using some kind of trick which is well working on .kv file or kv string but it does not working in the .py file, and that trick is I equal the font_size of button text to the (width/6) [font_size=another_widget.width/6] of the parent widget but there is not effect it does not get change dynamically and it will fixed the font_size only. I want to change the Button font size which is referred by main_text and Hint_text varaibles in the Source Code the line no. 36 and 46 respectively for these variables in the code The whole Source code is here:-

from kivymd.app import MDApp
from kivymd.uix.card import MDCard
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
from kivy.uix.screenmanager import ScreenManager,Screen
from kivymd.uix.fitimage import FitImage
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.core.text import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
class Elevation(RoundedRectangularElevationBehavior,MDCard):
    pass

class FirstWin(RoundedRectangularElevationBehavior,Screen):
    def __init__(self,**kwargs):
        super(FirstWin,self).__init__(**kwargs)
        # for i in range(0,10):
        mycard=Elevation(
            elevation=15,
            size_hint =(0.2,0.5),
            pos_hint={'center_x':0.5,'center_y':0.5},
            orientation='vertical',
            radius= [36, ],
            ripple_behavior=True,
            focus_behavior=True

        )
        image = FitImage(radius=[36,36,0,0],size_hint_y=3, size_hint_x=1,orientation="vertical")
        imagebutton = Button(background_normal="D:/Study/Python/Kivy/images/1.jpg",
                             background_down="D:/Study/Python/Kivy/images/1.jpg",
                             size_hint_y=550.0,
                             size_hint_x=1,
                              pos_hint={'x': 0, 'y': 0},
                             )
        texture_part = MDFloatLayout( md_bg_color=(46 / 255, 8 / 255, 211 / 255, .5),
                                     radius=[0, 0, 36, 36])
        main_text = Button(
            text="Tea and Coffee",
            halign="left",
            bold=True,
            pos_hint={'center_x': 0.3, 'top':1.2},
            size_hint=(1, None),
            font_size=mycard.width /6,
            background_normal='',
            background_color=(0, 0, 0, 0)
        )
        Hint_text = Button(
            text="Food Menu",
            halign="left",
            font_size=mycard.width/6,
            bold=True,
            color=(206 / 255, 203 / 255, 203 / 255, 0.2),
            pos_hint={'center_x': 0.2, 'top': 0.8},
            size_hint=(1, None),
            height=texture_part.height,
            background_normal='',
            background_color=(0, 0, 0, 0),
        )
        image.add_widget(imagebutton)
        mycard.add_widget(image)
        texture_part.add_widget(main_text)
        texture_part.add_widget(Hint_text)
        mycard.add_widget(texture_part)
        self.add_widget(mycard)



class SecondWin(Screen):
    pass
class MymdCard(MDApp):
    def build(self):
        sm = ScreenManager()
        self.theme_cls.theme_style = "Light"

        sm.add_widget(FirstWin(name='welcomeScreen'))
        sm.add_widget(SecondWin(name='functionScreen'))
        return sm




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

So I want the Solution that is by which trick or method can i able to change the font_size of the text of buttons dynamically. if yes so please let me know also. it will be very helpful for me. Thank You!!

CodePudding user response:

It works in kv because kv automatically sets up bindings to adjust properties that depend on other properties. But if you are not using kv, you must set up those bindings yourself. Without those bindings, the font_size values will be set based on the width of mycard at the time that the main_text and Hint_text Buttons are created, and will not be updated. Here is a modified version of your FirstWin class that does the bindings:

class FirstWin(RoundedRectangularElevationBehavior,Screen):
    def __init__(self,**kwargs):
        super(FirstWin,self).__init__(**kwargs)
        # for i in range(0,10):
        mycard=Elevation(
            elevation=15,
            size_hint =(0.2,0.5),
            pos_hint={'center_x':0.5,'center_y':0.5},
            orientation='vertical',
            radius= [36, ],
            ripple_behavior=True,
            focus_behavior=True
        )
        mycard.bind(size=self.adjust_sizes)  # This binding will cause the adjust_sizes() method to be triggered when mycard.size changes
        image = FitImage(radius=[36,36,0,0],size_hint_y=3, size_hint_x=1,orientation="vertical")
        imagebutton = Button(background_normal="D:/Study/Python/Kivy/images/1.jpg",
                             background_down="D:/Study/Python/Kivy/images/1.jpg",
                             size_hint_y=550.0,
                             size_hint_x=1,
                              pos_hint={'x': 0, 'y': 0},
                             )
        texture_part = MDFloatLayout( md_bg_color=(46 / 255, 8 / 255, 211 / 255, .5),
                                     radius=[0, 0, 36, 36])
        
        # save a reference to main_text
        self.main_text = Button(
            text="Tea and Coffee",
            halign="left",
            bold=True,
            pos_hint={'center_x': 0.3, 'top':1.2},
            size_hint=(1, None),
            font_size=mycard.width /6,
            background_normal='',
            background_color=(0, 0, 0, 0)
        )
        
        # save a reference to Hint_text
        self.Hint_text = Button(
            text="Food Menu",
            halign="left",
            font_size=mycard.width/6,
            bold=True,
            color=(206 / 255, 203 / 255, 203 / 255, 0.2),
            pos_hint={'center_x': 0.2, 'top': 0.8},
            size_hint=(1, None),
            height=texture_part.height,
            background_normal='',
            background_color=(0, 0, 0, 0),
        )
        image.add_widget(imagebutton)
        mycard.add_widget(image)
        texture_part.add_widget(self.main_text)
        texture_part.add_widget(self.Hint_text)
        mycard.add_widget(texture_part)
        self.add_widget(mycard)

    # This method adjusts the font_size properties
    def adjust_sizes(self, mycard, new_size):
        new_font_size = mycard.width / 6
        self.Hint_text.font_size = new_font_size
        self.main_text.font_size = new_font_size

CodePudding user response:

Everything is logical, if you write code in a kv file, the widget automatically monitors the change of arguments (you can look at the sources). In order for everything to work in the py file, you must specify the bind method. For your example, it will be like this:

# after creating Hint_text instance
mycard.bind(width=lambda inst, width: self.change_font(width, main_text, Hint_text))

...
# in FirstWin class
def change_font(self, width, main_text, Hint_text):
    main_text.font_size = width / 6
    Hint_text.font_size = width / 6

You can play with this example, it dynamically calculates the size of the text. If you don't want to use kv, just use bind as I indicated above.

from kivy.lang import Builder

from kivymd.app import MDApp

KV = '''
MDScreen:
    MDCard:
        id: card
        orientation: "vertical"
        size_hint: .8, .8
        pos_hint: {"center_x": .5, "center_y": .5}
        md_bg_color: [0, 1, 0, 1]
            
        MDLabel:
            text: "Ride the Lightning"
            theme_text_color: "Primary"
            font_size: max(min(sp(card.width / len(self.text)), sp(card.height)), sp(12))
            halign: 'center'
'''


class TestCard(MDApp):
    def build(self):
        return Builder.load_string(KV)


TestCard().run()
  • Related