Home > other >  Creating a label in python and adding it a background color after a button press in a kivy setup
Creating a label in python and adding it a background color after a button press in a kivy setup

Time:06-10

I want to create a label in python with a background color, after I press a button, in a kivy setup.

I have written below code and it is running without error however because of a mistake I cound not find, when I press the button, canvas is not created behind the label. How can I correct it ?

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle

class MyWinMan(ScreenManager):
    pass

class W_MainMenu(Screen):

    def button_press(self):

        lbl_info = Label(   
                            text                = 'Please select the file...',
                            size_hint           = ( 1, 0.6),
                            font_size           = 18,
                            color               = ( 180/255, 180/255, 180/255, 1),
                            )

        with lbl_info.canvas:
                Color( 50/255, 50/255, 50/255, 1)
                Rectangle(pos=lbl_info.pos, size=lbl_info.size)

        self.manager.get_screen("win_Main").ids.scr_Main_lvl_A.add_widget(lbl_info)


kv = Builder.load_string("""

MyWinMan:

    W_MainMenu:

<W_MainMenu>:
    
    name:           "win_Main"

    BoxLayout:

        id:             scr_Main_lvl_A
        orientation:    "vertical"
        size:           root.width, root.height
        padding:        40
        spacing:        10

        Button:
        
            text:       'Test'
            id:         btn_chk
            font_size:  20
            on_release: root.button_press()
             
""")

Window.size = (700, 460)
Window.top = 50
Window.left = 100

class MyApp(App):

    def build(self):
        return kv

if __name__ == '__main__':

    MyApp().run()

CodePudding user response:

I solved it by utilizing Clock.schedule_once as the pos and size values should be obtained after the creation of label but as I guess it was trying to get them before. Therefore I added a bit delay. However a better solution is always welcome...

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
from kivy.clock import Clock

class MyWinMan(ScreenManager):
    pass

class W_MainMenu(Screen):

    lbl_info = ""

    def create_my_label(self):

        self.lbl_info = Label(   
                            text                = 'Please select the file...',
                            size_hint           = ( 1, 0.6),
                            font_size           = 18,
                            color               = ( 180/255, 180/255, 180/255, 1),
                            )

        self.manager.get_screen("win_Main").ids.scr_Main_lvl_A.add_widget(self.lbl_info)

    def set_canvas(self, dt=0):

        with self.lbl_info.canvas:
            Color( 50/255, 50/255, 50/255, 1)
            Rectangle(pos=self.lbl_info.pos, size=self.lbl_info.size)

    def button_press(self):

        self.create_my_label()
        Clock.schedule_once(self.set_canvas)


kv = Builder.load_string("""

MyWinMan:

    W_MainMenu:

<W_MainMenu>:
    
    name:           "win_Main"

    BoxLayout:

        id:             scr_Main_lvl_A
        orientation:    "vertical"
        size:           root.width, root.height
        padding:        40
        spacing:        10

        Button:
        
            text:       'Test'
            id:         btn_chk
            font_size:  20
            on_release: root.button_press()
             
""")

Window.size = (700, 460)
Window.top = 50
Window.left = 100

class MyApp(App):

    def build(self):
        return kv

if __name__ == '__main__':

    MyApp().run()

CodePudding user response:

The Rectangle that you are creating in the canvas is using the size of the Label at the moment that the Label is created. At that moment the size and position of the Label are the default size of (100,100) and default position of (0,0). The Rectangle is not automatically updated when the Label size/position is updated. So you must either write code to do the updating, or use kv (it will handle the updating for you). So, I suggest creating a custom Label class that does what you want. First create a new Label class and use it in the py code:

class LabelInfoButton(Button):
    pass


class W_MainMenu(Screen):

    def button_press(self):
        lbl_info = LabelInfoButton(
            text='Please select the file...',
            size_hint=(1, 0.6),
            font_size=18,
            color=(180 / 255, 180 / 255, 180 / 255, 1),
        )

        # with lbl_info.canvas:
        #     Color(50 / 255, 50 / 255, 50 / 255, 1)
        #     Rectangle(pos=lbl_info.pos, size=lbl_info.size)

        self.manager.get_screen("win_Main").ids.scr_Main_lvl_A.add_widget(lbl_info)

and set the desired behavior in your kv:

<LabelInfoButton>:
    canvas.before:
        Color:
            rgba: 50 / 255, 50 / 255, 50 / 255, 1
        Rectangle:
            pos: self.pos
            size: self.size
  • Related