Daniela Paz
Daniela Paz

Reputation: 33

Kivy Programming, how to change color or image of a button by pressing another button

so me and my friends have been trying to code a game on kivy, but we are stuck at this point, we can't figure it out how to change a color or image of a button by pressing another one. The game is in a chessboard, we are trying to do a Fox & Hound game, so the idea is that when the user press a Hound, 2 blocks on the chessboard light up indicating where you can move, and then by pressing in one of them, change the image of de Hound to the one that was pressed.

Here is the code, hope you can help me with this, thanks.

from kivy.app import App
from kivy.graphics import *
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.config import Config

Window.size = (800, 800)

intento = 0
nroboton= [0,0]

class MainWindow(GridLayout): # main class
    def popbtns(self):
        i = 3
        self.add_widget(Label(text=' '))
        self.add_widget(Btn(id=str(i+3), size=(100, 100), background_color=(0,0,0,1)))
        i = i - 1

class Btn(Button): # button class
    def on_release(self):
        print('self.pos= ' + str(self.id))
    def on_press(self):
        global intento
        if(intento == 1):
            nroboton[1] = self.id
            print('moviendose de ' + str(nroboton[0]) + 'a ' + str(nroboton[1]))
            intento = 0
        else:
            nroboton[0] = self.id
            intento = 1
        print('llamada ssh ' + str(self.id))

class But(Button):
    def new(self):
        self.background_color=(0,250,0,1)

class Zorro(Button): # button class
    def on_release(self):
        print('self.pos= ' + str(self.id))
    def on_press(self):
        global intento
        if(intento == 1):
            nroboton[1] = self.id
            print('moviendose de ' + str(nroboton[0]) + 'a ' + str(nroboton[1]))
            intento = 0
        else:
            nroboton[0] = self.id
            intento = 1
        print('llamada ssh ' + str(self.id)) 

class MainApp(App):

    def build(self):

        main = MainWindow(cols=3, rows=1)
        self.root = main  # don't use global!
        # make background
        with main.canvas:
            Rectangle(pos=main.pos, size=(10000,10000))

        # populate gridlayout with Buttons
        #main.add_widget(Debug(text='debug', background_color=(1, 0, 0, 1)))
        main.popbtns()
        # print position of buttons...
        Clock.schedule_once(self.delayed_function, 0.1)

    def delayed_function(self, dt):
        self.print_buttons_pos()

    def print_buttons_pos(self):
        for child in self.root.children:
            print(str(child) + ' pos is ' + str(child.id))

if __name__ == "__main__":
    MainApp().run()

And here are the image of Hounds and Fox. Hound Fox

Ok so this is the all I could reduce it, hope it helps

Upvotes: 0

Views: 1370

Answers (1)

Wayne Werner
Wayne Werner

Reputation: 51907

Here's some code that shows you how to change the color of one button by pressing the other button.

I use the ids property of the parent window which is certainly one of the better ways to do this. I left a bunch of your code in here, but you'll notice that I ended out removing quite a bit, since that wasn't part of an MCVE.

from kivy.app import App
from kivy.graphics import *
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.lang import Builder

Window.size = (800, 800)

intento = 0
nroboton= [0,0]

setup = '''
MyGame:
    cols: 3
    rows: 2
    # This could have just been "Button"
    # and it would work just fine, too.
    Btn:
        # This ID is only valid inside the .kv
        # stuff, so we have to pass something
        # else to the pressed/released handlers
        id: hello_btn
        text: 'Hello'
        size: 100,100
        # These lines are how to identify the
        # button doing the pressing
        on_press: root.was_pressed('hello')
        on_release: root.was_released('hello')
    Btn:
        id: world_btn
        text: 'World'
        size: 100,100
        on_press: root.was_pressed('world')
        on_release: root.was_released('world')
'''

# I'm not using any of this code, you may want it
# if you're trying to do something special with the
# buttons you're creating. Otherwise just change
# Btn to Button
class Btn(Button): # button class
    def on_release(self):
        print('self.pos= ' + str(self.id))
    def on_press(self):
        global intento
        self.background_color = [1,1,1,1]

        print('IDs: ', self.parent.ids)
        if(intento == 1):
            nroboton[1] = self.id
            print('moviendose de ' + str(nroboton[0]) + 'a ' + str(nroboton[1])
            intento = 0
        else:
            nroboton[0] = self.id
            intento = 1
        print('llamada ssh ' + str(self.id))


class MyGame(GridLayout):
    def was_pressed(self, name):
        if name == 'hello':
            btn = self.ids['world_btn']
        elif name == 'world':
            btn = self.ids['hello_btn']
        btn.background_color = [255, 0, 0, 1]

    def was_released(self, name):
        if name == 'hello':
            btn = self.ids['world_btn']
        elif name == 'world':
            btn = self.ids['hello_btn']
        btn.background_color = [1, 1, 1, 1]


class MainApp(App):
    def build(self):
        return Builder.load_string(setup)

if __name__ == "__main__":
    MainApp().run()

Upvotes: 1

Related Questions