Changing property of specific Label from a list (array) of Python tkinter Labels is not working out as expected

Viewed 191

This code is for a Bingo game in Python tkinter. The interface has a list of 3 name labels (a Label array, lblName) and another list of 5 columns for each player (a Label array, lblNums), containing numbers selected by the players.

Each time the lblNums Label array is created, its bg color is set to yellow without any use of subscripts.

The "players" list contains the names of players and their chosen numbers.

Inside click(), a number is randomly generated on each click. If it matches the number selected by one or more players, any lblNums that matches that number bg color should change to green (Line 31). However, whenever a player's number matches the random number, it is always lblNums' last row - last columns that changes color. Do I need to use subscripts to change the correct cell's color? My code is:

from tkinter import Tk, Label, Button
from random import randint

win = Tk()
win.geometry("350x300+0+0")
win.title("B I N G O")

players = [["Jason",  [0, 1, 2, 3, 4]],
           ["Sheena", [3, 4, 5, 6, 7]],
           ["Arthur", [5, 6, 7, 8, 9]]
          ]

for i in range(3):
    lblName = Label(win, text=players[i][0], width=10, font=("Consolas", 16, "bold"), anchor="e").place(x=10, y=i*30)

for j in range(3):
    for k in range(5):
        lblNums = Label(win, text=str(players[j][1][k]), font=("Helvetica", 16, "bold"), bg="yellow", width=2, anchor="e")
        lblNums.place(x=150+k*35, y=j*30)

def click():
    num = randint(0, 9)
    for i in range(3):
        for j in range(5):
            print(num, players[i][1][j])
            if players[i][1][j] == num:
                print("Match")
                lblNums.config(bg="green")
        print()
    print("===========")

btn = Button(win, text="Click", command=click)
btn.place(x=100, y=220)

win.mainloop()

The following sample output shows that number 6 was randomly drawn and a match was found for Players 2 & 3. So, Row 2 Col 4 and Row 3 Col 2 of lblNums should have turned green. But instead, only Row 3 Col 5 changes color.

6 0

6 1

6 2

6 3

6 4

6 3

6 4

6 5

6 6

Match

6 7

6 5

6 6

Match

6 7

6 8

6 9

1 Answers

At the moment, you are changing the colour of labelNums. This refers to the last Label you made, so therefore it's always the bottom right corner that gets highlighted. Here's my solution:

labelList = []
for j in range(3):
    row = []
    for k in range(5):
        lblNums = Label(win, text=str(players[j][1][k]), font=("Helvetica", 16, "bold"), bg="yellow", width=2, anchor="e")
        lblNums.place(x=150+k*35, y=j*30)
        row.append(lblNums)
    labelList.append(row)

def click():
    num = randint(0, 9)
    for i in range(3):
        for j in range(5):
            print(num, players[i][1][j])
            if players[i][1][j] == num:
                print("Match")
                labelList[i][j].config(bg="green")
        print()
    print("===========")

There needs to be a reference to all the labels so you can modify them later. To do this, I've added a list called labelsList. Then when you make the labels, there is a list for each row, each item in the row is appended to the row list which is then appended to labelsList. Then in click() when you've found a match, you can use labelsList to find the Label you need using the row/column and then change it's colour.

Related