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()