Search code examples
pythonpython-2.7kivysetattributesetattr

How to change kivy NumericProperty object atrribute by pressing button in other screen


In our app, we have a GameScreen that has a NumericProperty object that displays a player's score (GameScreen_player1_score). On a separate ClueScreen (using kivy Screen Manager) we have a ClueAnswerButton1 that should change the player's score on the GameScreen when pressed. How do we change the score attribute of the player's score on GameScreen when the user presses the correct ClueAnswerButton1 on the ClueScreen?

We've tried creating a player1_score variable in the ClueScreen that pulls from the GameScreen but get the error:

TypeError: attribute name must be string, not 'int'

main.py code is here:

class GameScreen(Screen):
    GameScreen_player1_score = NumericProperty(0)
    ...


class ClueScreen(Screen):
    ...

    def check_choice(self):
        player1_score = self.manager.get_screen('game_home').GameScreen_player1_score

        if self.choice0.state == 'down':
            if self.choice0.text == self.correct:
                self.message.text = "[color=006600]Correct! Click back to game and keep" \
                        "playing![/color]"
                self.choice0.background_disabled_down = 'atlas://img/myatlas/green_button5'
                setattr(self,player1_score, +10)
                return
            else:
                self.message.text = "Try again"
                self.choice0.background_disabled_down = 'atlas://img/myatlas/red_button5'
                self.choice0.disabled = True

class GameApp(App):

    sm = ScreenManager()
    use_kivy_settings = False

    def build(self):

    self.sm.add_widget(GameScreen(name='game_home'))
    self.sm.add_widget(SheddClue0Screen(name='game_clue0'))

    return self.sm


if __name__ == '__main__':
    GameApp().run() 

bingo.kv code is here:

<GameScreen>:
    GeneralFloatLayout:
    GeneralAnchorLayout:
        GeneralBoxLayout:
            ScoreGridLayout:
                ScoreBoardLabel:
                    text: '[color=0046C3]Player 1[/color]'
                ScoreBoardLabel:
                    text: str(root._player1_score)

<ClueScreen>:
    message: message
    choice0: choice0
    choice1: choice1
    choice2: choice2
    choice3: choice3

    ClueBoxLayout:
        ClueLabel:
            text: "[color=0046C3]" + "Put label Here" + "[/color]"
        ClueMessage:
            id: message
        ClueAnswerButton1:
            id: choice0
            on_press: root.check_choice()
        ClueAnswerButton1:
            id: choice1
            on_press: root.check_choice()
        ClueAnswerButton1:
            id: choice2
            on_press: root.check_choice()
        ClueAnswerButton1:
            id: choice3
            on_press: root.check_choice()
        ClueGridLayout:
            ReturnButton:
                text: 'Back to game'
                on_press: root.manager.current = 'game_home'

Solution

  • Edit your check_choice method as follows:

    def check_choice(self):
        player1_score = self.manager.get_screen('game_home')
    
        if self.choice0.state == 'down':
            if self.choice0.text == self.correct:
                self.message.text = "[color=006600]Correct! Click back to game and keep" \
                        "playing![/color]"
                self.choice0.background_disabled_down = 'atlas://img/myatlas/green_button5'
                setattr(player1_score, 'GameScreen_player1_score', +10)
                return
            else:
                self.message.text = "Try again"
                self.choice0.background_disabled_down = 'atlas://img/myatlas/red_button5'
                self.choice0.disabled = True