I am making a Sudoku board (not a solver) and I want to disable (or at least change the background color of some buttons based on clicked status of other buttons. For example, if a "1" is selected in the 1st row, 7th column, I want to disable the "1" buttons of all other cells in the 1st row and in the 7th column and in the top right block.
Ive given each button a __name__
as below (in my example the __name__
would be [3, 1, 7, 1, 1]), so I would like all button with addresses [3, x, y, z, 1], [*, 1, *, , 1], and [, *, 7, *, 1] to be disabled, or at least grayed-out.
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
class SudokuLayout(GridLayout):
def __init__(self, **kwargs):
super(SudokuLayout, self).__init__(**kwargs)
self.cols = 3
self.rows = 3
i_block = 0
i_cell = 0
i_row = 0
i_col = 0
i_inner = 0
# Building grid and naming buttons
for i_block in range(1, 10):
dynamic_grid_name = f"Block_{i_block}"
globals()[dynamic_grid_name] = GridLayout(cols=3, rows=3, padding=2)
for i_cell in range(1, 10):
dynamic_cells_name = f"Cell_{i_cell}"
globals()[dynamic_cells_name] = GridLayout(cols=3, rows=3, padding=1)
for i_inner in range(1, 10):
btn = Button(text=str(i_inner))
if i_block <= 3:
if i_cell <= 3:
i_row = 1
elif 4 <= i_cell <= 6:
i_row = 2
elif i_cell >= 7:
i_row = 3
elif 4 <= i_block <= 6:
if i_cell <= 3:
i_row = 4
elif 4 <= i_cell <= 6:
i_row = 5
elif i_cell >= 7:
i_row = 6
elif i_block >= 7:
if i_cell <= 3:
i_row = 7
elif 4 <= i_cell <= 6:
i_row = 8
elif i_cell >= 7:
i_row = 9
if i_block == 1 or i_block == 4 or i_block == 7:
if i_cell == 1 or i_cell == 4 or i_cell == 7:
i_col = 1
elif i_cell == 2 or i_cell == 5 or i_cell == 8:
i_col = 2
elif i_cell == 3 or i_cell == 6 or i_cell == 9:
i_col = 3
elif i_block == 2 or i_block == 5 or i_block == 8:
if i_cell == 1 or i_cell == 4 or i_cell == 7:
i_col = 4
elif i_cell == 2 or i_cell == 5 or i_cell == 8:
i_col = 5
elif i_cell == 3 or i_cell == 6 or i_cell == 9:
i_col = 6
elif i_block == 3 or i_block == 6 or i_block == 9:
if i_cell == 1 or i_cell == 4 or i_cell == 7:
i_col = 7
elif i_cell == 2 or i_cell == 5 or i_cell == 8:
i_col = 8
elif i_cell == 3 or i_cell == 6 or i_cell == 9:
i_col = 9
btn.__name__ = [i_block, i_row, i_col, i_cell, i_inner]
btn.bind(on_press=self.pressed)
globals()[dynamic_cells_name].add_widget(btn)
globals()[dynamic_grid_name].add_widget(globals()[dynamic_cells_name])
self.add_widget(globals()[dynamic_grid_name])
def pressed(self, btn):
print(btn.__name__)
if btn.background_color == [0.5, 5, 0.5, 1]:
btn.background_color = [.1, .1, .1, 1]
elif btn.background_color == [.1, .1, .1, 1]:
btn.background_color = [1, 1, 1, 1]
elif btn.background_color == [1, 1, 1, 1]:
btn.background_color = [0.5, 5, 0.5, 1][enter image description here][1]
class Example(App):
def build(self):
return SudokuLayout()
if __name__ == '__main__':
x = Example()
x.run()
I don't know where to begin. I've found a lot of information on doing something once a button is selected, but nothing on how to check all of the buttons by __name__
.
I would like to loop through each button and compare it's __name__
to the clicked button, and then change it's attribute if it matches. Something like:
#Check row
For x in range(1, 10):
if button.__name__[*, 1, x, *, 1] == clicked_btn.__name__
button.background_color = [.1, .1, .1, 1]
There's a lot of code there but I think I get what your looking for. You want to apply a function to each button that does "all button with addresses [3, x, y, z, 1], [*, 1, *, , 1], and [, *, 7, *, 1] to be disabled, or at least grayed-out." I'm not sure what the function coding will be but what you can do is create a list...
for i_inner in range(1, 10):
btn = Button(text=str(i_inner))
self.btn_list.append(btn)
...then later, instead of check row you could loop through the list of all buttons
#Check all buttons
For button in self.btn_list:
if button.__name__[*, 1, x, *, 1] == clicked_btn.__name__
button.background_color = [.1, .1, .1, 1]
Depending on how you want to access btn_list making it a class variable might be more appropriate
SudokuLayout.btn_list.append(btn)