Search code examples
pythonkivykivy-language

Activate a ToggleButton based on the "down" state of four other ToggleButton 's


Been stuck on this for a couple of days, decided to ask the kivy community!

Currently trying to figure out how to

-activate a ToggleButton based on the toggle state of four other ToggleButton s

Here is a picture of the interface: enter image description here

Activating "down" state on Toggle1, Toggle2, Toggle3, and Toggle4 should activate MainToggle1

Here is what I have so far:

main.py
from kivy.app import App
from kivy.properties import StringProperty, BooleanProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget

class ExternalTrigger(BoxLayout):
    buttonState = BooleanProperty(False)
    def on_activated_state(self, widget):
        if widget.state == "normal":
            self.buttonState = False
        elif widget.state == "down":
            self.buttonState = True

class BoxLayoutExample(BoxLayout):
    pass

class BoxLayoutApp(App):
    pass

BoxLayoutApp().run()

BoxLayout.kv

BoxLayoutExample:

<ExternalTrigger@BoxLayout>:
    ToggleButton:
        text: "MainToggle1"
        on_state: root.on_activated_state(self)
        disabled: root.on_activated_state(self)

<BoxLayoutExample@PageLayout>:
    orientation: "vertical"
    BoxLayout:
        orientation: "horizontal"
        ExternalTrigger:
        GridLayout:
            size_hint: 2, 1
            cols: 2
            ToggleButton:
                background_color: (0,0,1)
                text: "Toggle1"
            ToggleButton:
                background_color: (0,1,0)
                text: "Toggle2"
            ToggleButton:
                background_color: (1,0,0)
                text: "Toggle3"
            ToggleButton:
                background_color: (7,1,3)
                text: "Toggle4"

Advice would be appreciated!


Solution

  • Use the id property and a custom class of ToggleButton.

    The class you have to add:

    class MyToggleButton(ToggleButton):
        # This method will check if all the ToggleButtons are "down" state
        def checkAllButtons(self, btn1, btn2, btn3, btn4):
            if (btn1.state == 'down') and (btn2.state == 'down') and (btn3.state == 'down') and (btn4.state == 'down'):
                return 'down'
            else:
                return 'normal'
    

    In you .kv file add a custom property to the class <ExternalTrigger@BoxLayout>: and bind it to the state of the main ToggleButton:

    <ExternalTrigger@BoxLayout>:
        custom: 'normal'
        ToggleButton:
            text: "MainToggle1"
            on_state: root.on_activated_state(self)
            disabled: root.on_activated_state(self)
            state: root.custom
    

    Then add the id to each ToggleButton and evaluate on_press event if the four ToggleButtons are "down" (do this with the method created in the custom class).

    Change all the four ToggleButtons you have to the folling:

    
    MyToggleButton:
        id: but1  # Here obviously change the id, for example in ToggleButton2: id=but2
        background_color: (0,0,1)
        text: self.state
        on_press: ext.custom=self.checkAllButtons(but1,but2,but3,but4) #This remains the same for every ToggleButton