jpolache
jpolache

Reputation: 305

disable a group of buttons in kivy

This is my first kivy app.

My app starts looking like this enter image description here

When the start button is pressed, a group of digits is displayed for 3 seconds. Then the app looks like this enter image description here

After selecting the digits, the button reappears and the number pad goes back to opacity = 0enter image description here

The number pad is hidden, but the buttons still work.

The number buttons are in a Grid Layout. I am turning the opacity of the layout from 0 to 1 to hide the buttons, but "disabled = True" of the layout does not apply to the buttons. Having hidden buttons that are not disabled can be a problem :)

I can use a loop to disable all the children of the layout. I can remove the button widgets and put them back.

What's the pythonic solution? Here's the code;

# test3.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
# from kivy.uix.gridlayout import GridLayout
# from kivy.uix.floatlayout import FloatLayout
# from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.clock import Clock
import random



Builder.load_string('''
<NumberButton@Button>:
    background_color: [0, 0, 1, 1]

<ContainerBox>:
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            id: root.state_box
            orientation: 'horizontal'
            Label:
                id: state_label
                halign: 'center'
                text: "Memory Trainer\\nMemorize the numbers\\nClick start to begin"
                font_size: '20'
        NumberBox:
            id: label_box
            orientation: 'horizontal'
        AnchorLayout:    
            id: lLout
            anchor_x: 'center'
            anchor_y: 'center'
            GridLayout:
                opacity: 0
                disabled: True
                cols: 3
                row_default_height: '60'
                col_default_width: '60'
                size_hint: None, None   
                id: button_grid            
                NumberButton:
                    text: "1"
                    on_release: root.add_guess(1)
                NumberButton:
                    text: "2"
                    on_release: root.add_guess(2)
                NumberButton:
                    text: "3"
                    on_release: root.add_guess(3)
                NumberButton:
                    text: "4"
                    on_release: root.add_guess(4)
                NumberButton:
                    text: "5"
                    on_release: root.add_guess(5)
                NumberButton:
                    text: "6"
                    on_release: root.add_guess(6)
                NumberButton:
                    text: "7"
                    on_release: root.add_guess(7)
                NumberButton:
                    text: "8"
                    on_release: root.add_guess(8)
                NumberButton:
                    text: "9"
                    on_release: root.add_guess(9)
        AnchorLayout:
            anchor_x: 'center'
            anchor_y: 'center'
            Button:
                id: action_button
                opacity: 1
                disabled: False
                text: "start"
                width: '150'
                height: '50'
                size_hint_y: None
                size_hint_x:None
                on_release: app.root.add_labels()

''')

how_many = 2
guess_list = []
correct = 0
check_guess = 0
label_list = []


def rand_list_numbers():
    rand_list = []
    x = 0
    while len(rand_list) < how_many:  # get test numbers
        y = random.randint(1, 9)  # rand num between 1 and  9
        if y not in rand_list:  # if the number is not in the list
            rand_list.append(y)  # add the number to the list
    return rand_list



class ContainerBox(BoxLayout):


    def __init__(self, **kwargs):
        super(ContainerBox, self).__init__(**kwargs)


    def guess_callback(self, x):
        self.ids.label_box.clear_widgets()
        self.ids.button_grid.opacity = 1
        self.ids.button_grid.disabled = False
        self.ids.state_label.text = "pick the numbers from the keypad"


    def add_labels(self):
        self.ids.action_button.opacity = 0
        self.ids.action_button.disabled = True
        global label_list
        global guess_list
        guess_list == []
        self.ids.label_box.clear_widgets()
        label_list = rand_list_numbers()
        for t_number in label_list:
            str_number = str(t_number)
            self.ids.label_box.add_widget(Label(text=str_number, font_size="75"))
        self.ids.state_label.text = "now using " + str(how_many) + " digits"
        Clock.schedule_once(self.guess_callback, 3)


    def add_guess(self, guess_number):
        global label_list
        global guess_list
        global correct
        global how_many
        global check_guess
        guess_list.append(guess_number)
        str_guess_number = str(guess_number)
        self.ids.label_box.add_widget(Label(text=str_guess_number, font_size="75", width = "30"))
        self.ids.state_label.text = "you have picked " + str(len(guess_list)) + " number(s) of " + str(how_many) + " numbers"
        # all the guesses have been made
        if len(label_list) == len(guess_list):
            self.ids.button_grid.opacity = 0
            self.ids.button_grid.diasbled = True
            check_guess = 1
            # do the guesses match the random numbers?
            if(label_list == guess_list):
                self.ids.state_label.text = "that's right! click next"
                self.ids.action_button.text = "next"
                self.ids.action_button.opacity = 1
                self.ids.action_button.disabled = False
                correct += 1
                #were there 3 correct guesses in a row?
                if correct == 2:
                    correct = 0
                    how_many += 1
            else:
                self.ids.state_label.text = "click next to try again"
                self.ids.action_button.text = "next"
                self.ids.action_button.opacity = 1
                self.ids.action_button.disabled = False
                correct = 0
            guess_list = []



class NumberBox(BoxLayout):
    pass


class TestApp(App):

    def build(self):
        return ContainerBox()


if __name__ == '__main__':``
    TestApp().run()

Upvotes: 0

Views: 1159

Answers (1)

ikolim
ikolim

Reputation: 16031

Use a for loop to traverse the children of numpad.

Snippets

def disable_numpad(self):
    for child in reversed(self.ids.button_grid.children):
        if isinstance(child, Button):
            child.disabled = not child.disabled
            child.opacity = 0 if child.disabled else 1

Upvotes: 1

Related Questions