I am writing a chess program and I can't get the pieces to output since I changed the text from being defined with text to text variable and now I can't get string working to output the pieces. I define the buttons in a for loop and it outputs nothing in the squares. The code is
def drawboard(self):
x=0
y=0
for column in range(self.n):
self.changecolours()
x=x+1
y=0
for row in range(self.n):
y=y+1
colour = self.colours[self.colourindex]
pos=(x,9-y)
buttons=(tk.Button(self.boardframe, padx=10, textvariable=lambda position=pos: self.placepieces(position), borderwidth=0, bg=colour, relief="solid", font=self.piecefont, command=lambda position=pos: self.movepiece(position) ))
buttons.grid(column=(x-1), row=(y-1), sticky="W"+"E"+"N"+"S" )
self.changecolours()
@classmethod
def placepieces(cls, position):
black=Black()
white=White()
squareposition=position
icon=tk.Stringvar("")
if squareposition in white.position.values():
for key in white.position:
value=white.position.get(key)
if value==squareposition:
if key.endswith("pawn"):
icon.set(white.pawntype[key])
elif key=="king":
icon.set(white.PIECES.get("KING"))
elif key=="queen":
icon.set(white.PIECES.get("QUEEN"))
elif key.endswith("bishop"):
icon.set(white.PIECES.get("BISHOP"))
elif key.endswith("knight"):
icon.set(white.PIECES.get("KNIGHT"))
else:
icon.set(white.PIECES.get("ROOK"))
else:
pass
elif squareposition in black.position.values():
for key in black.position:
value=black.position.get(key)
if value==squareposition:
if key.endswith("pawn"):
icon.set(black.pawntype.get(key))
elif key=="king":
icon.set(black.PIECES.get("KING"))
elif key=="queen":
icon.set(black.PIECES.get("QUEEN"))
elif key.endswith("bishop"):
icon.set(black.PIECES.get("BISHOP"))
elif key.endswith("knight"):
icon.set(black.PIECES.get("KNIGHT"))
else:
icon.set(black.PIECES.get("ROOK"))
break
else:
pass
else:
icon.set("")
return icon
How does stringvar work with textvariable?
In the case of a Button, you can configure the text to be displayed in one of two ways: with a hard-coded string (eg: text='click me'
) or with the textvariable
attribute.
The textvariable
attribute must be set to an instance of one of the special tkinter variable objects StringVar
, IntVar
, DoubleVar
or BooleanVar
(eg: var=tk.StringVar(); Button(..., textvariable=var)
). When configured with an instance of one of these variables, the text on the button will display whatever the value of the variable is.
Internally, when you specify a textvariable
, tkinter will take the string representation of that object and create a tcl variable in the embedded interpreter. So, while it may see to accept a standard variable, command, or even a lambda, it ultimately ends up creating an internal tcl variable with that name, and associates that internal variable with the underlying tcl widget. If you do not use one of the special variables, it is going to be difficult for you to get or set the value of that variable.
For example, consider this set of commands:
var = tk.StringVar(value="hello")
tk.Button(root, textvariable=var)
When that code is run, the text that appears on the button will be hello
. If you change the variable at any time (eg: var.set("goodbye")
), the button will automatically be changed to show the new value.