Search code examples
pythonuser-interfacekivykivymd

How To Show Text and Images With a Switch using KivyMD?


I'm trying to make a simple program that, right now, needs to have two functions.

The app has four images displayed at the top and for words in the middle. There are two switches in the bottom left corner, one to toggle text and the other to toggle images.

How would one use the switches to enable/disable the images and the text?

Here's a screenshot of the program. Below is the current code.

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window

Window.size = (1280, 720)

class MyAppApp(MDApp):
    height = '185dp'
    width = '250dp'
    text = 'airplane   bicycle   boat   canoe'
    x = 0
    def build(self):
        return Builder.load_string('''

FloatLayout:

    MDLabel:
        text: 'Images'
        font_size: dp(18)
        halign: 'center'
        pos_hint: {'center_x': 0.1075, 'center_y': 0.135}
    
    MDLabel:
        text: 'Text'
        halign: 'center'
        pos_hint: {'center_x': 0.098, 'center_y': 0.075}
        font_size: dp(18)

    MDSwitch:
        active: True 
        width: dp(40)
        pos_hint: {'center_x': 0.05, 'center_y': 0.135}
    
    MDSwitch:
        active: True
        width: dp(40)
        pos_hint: {'center_x': 0.05, 'center_y': 0.075}

    MDToolbar:
        pos_hint: {'top': 1}
        md_bg_color: [0, 106/255, 163/255, 1]
        title: 'Images'
        elevation: 20

    FitImage:
        size_hint_y: None
        size_hint_x: None
        height: app.height
        width: app.width
        radius: 36, 36, 36, 36
        elevation: 20
        source: 'images/transportation/Airplane.jpg'
        pos_hint: {'center_x': 0.2, 'center_y': 0.7}
    
    FitImage:
        size_hint_y: None
        size_hint_x: None
        height: app.height
        width: app.width
        radius: 36, 36, 36, 36
        elevation: 20
        source: 'images/transportation/Bicycle.jpg'
        pos_hint: {'center_x': 0.4, 'center_y': 0.7}
    
    FitImage:
        size_hint_y: None
        size_hint_x: None
        height: app.height
        width: app.width
        radius: 36, 36, 36, 36
        elevation: 20
        source: 'images/transportation/Boat.jpg'
        pos_hint: {'center_x': 0.6, 'center_y': 0.7}
    
    FitImage:
        size_hint_y: None
        size_hint_x: None
        height: app.height
        width: app.width
        radius: 36, 36, 36, 36
        elevation: 20
        source: 'images/transportation/Canoe.jpg'
        pos_hint: {'center_x': 0.8, 'center_y': 0.7}
    
    MDLabel:
        text: app.text
        halign: 'center'
        pos_hint: {'center_y': 0.375}
        font_size: dp(56)
    
'''
)

MyAppApp().run()

Any help would be greatly appreciated. Thanks!


Solution

  • To turn on/off the text, you can define a method in your App class that adjusts the opacity of the MDLabel, like this:

    def switch_text(self, switch_instance):
        text_widget = self.root.ids.text
    
        if switch_instance.active:
            text_widget.opacity = 1
        else:
            text_widget.opacity = 0
    

    This requires adding an id to your kv:

    MDLabel:
        id: text  # added id
        text: app.text
        halign: 'center'
        pos_hint: {'center_y': 0.375}
        font_size: dp(56)
    

    And an on_active: entry for the MDSwitch:

    MDSwitch:
        active: True
        width: dp(40)
        pos_hint: {'center_x': 0.05, 'center_y': 0.075}
        on_active: app.switch_text(self)  # triggers method call when active changes
    

    You can do the same type of thing for the Images, but you may need to add an id for each Image and change the opacity for each.

    Using opacity just makes the widget invisible, but it still hold its position in the GUI. You could change the size of those widgets (to (0,0)) instead, if you want to open up the space that they occupy in the GUI.