0

I've started learning python recently. I have little experience in gui and wanted to learn some more. With little research, I've found tkinter to make it real. As a project, decided to make the game mastermind.

What I'm doing is putting some rows with OptionMenu with the available colors. On the right I've put a confirm button, that has the command "validate" set. The thing is that I want to pass different values to each button (the frame and the row) with the following code, the problem I have is that it says that the row is always 9.

I've thought a possible solution, that is to reset at the end y=0 and every time I press the button add 1. But I think it should be simpler.

from tkinter import *

def selectedColor(var):
    print("Value is: " + var)

def validate(frame, row):
    # pass
    print("Frame: " + str(frame) + " row: " + str(row))
    rowToValidate = frame.nametowidget("." + str(row))
    for x in range(0,4):
        columnValue = frame.nametowidget("." + str(x) + str(row))
        print(columnValue)

master = Tk()

OPTIONS

 = [
    "RED",
    "BLUE",
    "YELLOW",
    "VIOLET",
    "ORANGE",
    "GREEN",
    "BROWN",
    "WHITE",
    "BLACK"
]

colorQuantity = 4
tries = 10
for y in range(0, tries):
    frame = Frame(master, name=str(y))
    isEnabled = "disabled" if y != 0 else "normal"
    for x in range(0,colorQuantity):
        variable = StringVar(frame, name=str(x)+str(y))
        variable.set("Choose color") # default value
        # print(str(variable))

        w = OptionMenu(frame, variable, *OPTIONS, command=selectedColor)        
        w.configure(state=isEnabled)
        w.pack(side=LEFT)
    confirmButton = Button(frame, text="Confirm", command= lambda: validate(frame, y+1))
    confirmButton.configure()
    confirmButton.pack(side=TOP)
    print(str(frame))
    frame.pack(side=TOP)


master.mainloop()   
j_4321
  • 15,431
  • 3
  • 34
  • 61
Silkking
  • 250
  • 3
  • 15
  • You have a problem because of the `lambda` in a for loop (see https://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture/2295372#2295372 and https://stackoverflow.com/questions/17677649/tkinter-assign-button-command-in-loop-with-lambda) – j_4321 Aug 10 '18 at 14:08

1 Answers1

1

I would save the OptionMenu variables in a list, to make it easier to retrieve their values. By using partial (link) in the command option, you can make sure each row get the correct row number as input.

See the code below (I've also added a bit of formatting on the dropdowns):


from tkinter import *
from functools import partial

def selectedColor(var):
    print("Value is: " + var)

def validate(args):
    frame = args[0]
    row = args[1]

    for x in range(0,4):
        print(rows[row][x].get())

master = Tk()

OPTIONS = [
    "RED",
    "BLUE",
    "YELLOW",
    "VIOLET",
    "ORANGE",
    "GREEN",
    "BROWN",
    "WHITE",
    "BLACK"
]

colorQuantity = 4
tries = 10
rows =[]
for y in range(0, tries):
    frame = Frame(master, name=str(y))
    isEnabled = "disabled" if y != 0 else "normal"
    row = []
    for x in range(0,colorQuantity):
        variable = StringVar(frame, name=str(x)+str(y))
        variable.set("Choose color") # default value
        # print(str(variable))
        row.append(variable)

        w = OptionMenu(frame, variable, *OPTIONS, command=selectedColor)  
        w.configure(width=len("Choose color"))      
        w.configure(state=isEnabled)
        w.pack(side=LEFT)
    rows.append(row)
    confirmButton = Button(frame, text="Confirm", command=partial(validate,(frame, y)))
    confirmButton.configure()
    confirmButton.pack(side=TOP)
    print(str(frame))
    frame.pack(side=TOP)


master.mainloop()

ThijsW
  • 2,599
  • 15
  • 17