2

So I am trying to take values out of three radio buttons, each having their own boolean assigned to them, and even though my buttons really do change their own values, they don't seem to change the values assigned in the value:attribute.

This is the python code that handles it:

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.properties import BooleanProperty
from kivy.graphics import *

class CliClicker(BoxLayout):

    blue = ObjectProperty(True)
    red = ObjectProperty(False)
    green = ObjectProperty(False)

    def bg_change(self):
        #Change background according value set in radio buttons
        if self.blue:
            print('color changed to blue')
            with self.menuoptions.canvas:
                Color(rgba=(.7,.7,.9,1))
        elif self.red:
            print('color changed to red')
            with self.menuoptions.canvas:
                Color(rgba=(.9,.7,.7,1))
        elif self.green:
            print('color changed to green')
            with self.menuoptions.canvas:
                Color(rgba=(.7,.9,.7,1))

    def show_value(self, instance, value, box):
        self.value = box
        print(instance, box, self.value)
        print('blue', self.blue)
        print('red', self.red)
        print('green', self.green)

class MainApp(App):

    def build(self):
        return CliClicker()

app = MainApp()
app.run()

I included a method that I use to check the state of each value

And this is the Kivy part of the code:

<OptionButton@Button>:
    size_hint: (None,None)
    width: 200
    height: 40

<CliClicker>:
    orientation: "vertical"
    id: cliclicker
    menuoptions: menuopts

    TabbedPanel:
        do_default_tab: False
        height: 200
        id: tabs

        TabbedPanelItem:
            text: "Menu"
            id: menu

            FloatLayout:
                id: menuopts
                canvas:
                    Color:
                        rgba: .7,.7,.9,1
                    Rectangle:
                        pos: self.pos
                        size: self.size

                OptionButton:
                    text: 'Option 1'
                    pos_hint: {'right':.63, 'top':.9}

                OptionButton:
                    text: 'Option 1'
                    pos_hint: {'right':.63, 'top':.8}

                GridLayout:
                    cols: 6
                    size_hint: (None, None)
                    pos_hint: {'top': .7, 'right':.69}
                    height: 40
                    width: 300

                    canvas:
                        Color:
                            rgba: .9,.9,.9,1
                        Rectangle:
                            pos: self.pos
                            size: self.size

                    CheckBox:
                        group: "bg_color"
                        value: root.blue
                        on_active: cliclicker.show_value(self, self.value, self.active)
                        color: 0,0,0,1
                    Label:
                        text: 'blue'
                        color: 0,0,0,1
                    CheckBox:
                        group: "bg_color"
                        value: root.red
                        on_active: cliclicker.show_value(self, self.value, self.active)
                        color: 0,0,0,1
                    Label:
                        text: 'red'
                        color: 0,0,0,1
                    CheckBox:
                        group: "bg_color"
                        value: root.green
                        on_active: cliclicker.show_value(self, self.value, self.active)  
                        color: 0,0,0,1
                    Label:
                        text: 'green'
                        color: 0,0,0,1
Fireball24
  • 53
  • 6

1 Answers1

1

I think the main problem is that you do not understand what the following means

value: root.blue

I think that you think root.blue change if active it changes but it is vice versa, what you are pointing out is that every time you change root.blue you change the status of the Checkbox and obviously you have never changed the root.blue so the active will not be updated. The idea is vice versa:

<CliClicker>:
    blue: checkbox_blue.active
    # ...
    CheckBox:
        id: checkbox_blue
        group: "bg_color"

But even so it is a bad idea, it is always good to consider that each functionality is a black box that receives inputs and obtains outputs, in this case the output is the color so we create a custom widget that inherits from GridLayout and exposes the property color:

*.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class CliClicker(BoxLayout):
    pass

class MainApp(App):
    def build(self):
        return CliClicker()

if __name__ == '__main__':
    MainApp().run()รง

*.kv

<OptionButton@Button>:
    size_hint: (None,None)
    width: 200
    height: 40

<ColorSelector@GridLayout>:
    cols: 6
    color_sel: (.7,.7,.9,1)
    canvas:
        Color:
            rgba: .9,.9,.9,1
        Rectangle:
            pos: self.pos
            size: self.size
    CheckBox:
        group: "bg_color"
        color: 0,0,0,1
        active: True
        on_active: if self.active: root.color_sel = .7,.7,.9,1
    Label:
        text: 'blue'
        color: 0,0,0,1
    CheckBox:
        group: "bg_color"
        color: 0,0,0,1
        on_active: if self.active: root.color_sel = .9,.7,.7,1
    Label:
        text: 'red'
        color: 0,0,0,1
    CheckBox:
        group: "bg_color"
        color: 0,0,0,1
        on_active: if self.active: root.color_sel = .7,.9,.7,1
    Label:
        text: 'green'
        color: 0,0,0,1

<CliClicker>:
    orientation: "vertical"
    id: cliclicker
    menuoptions: menuopts

    TabbedPanel:
        do_default_tab: False
        height: 200
        id: tabs

        TabbedPanelItem:
            text: "Menu"
            id: menu

            FloatLayout:
                id: menuopts
                color_property:  (.7,.7,.9,1)
                canvas:
                    Color:
                        rgba: self.color_property
                    Rectangle:
                        pos: self.pos
                        size: self.size

                OptionButton:
                    text: 'Option 1'
                    pos_hint: {'right':.63, 'top':.9}

                OptionButton:
                    text: 'Option 1'
                    pos_hint: {'right':.63, 'top':.8}
                ColorSelector:
                    id: selector
                    size_hint: (None, None)
                    pos_hint: {'top': .7, 'right':.69}
                    height: 40
                    width: 300
                    on_color_sel: menuopts.color_property = self.color_sel

enter image description here

enter image description here

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241