I_Queerly_Belong_Here
I_Queerly_Belong_Here

Reputation: 15

bind lambda of function to key event python

I wrote a small painting game, but it currently uses GUI buttons instead of reading key presses.

How can I make it read key presses to have the same output as what the GUI buttons currently do?

I haven't been able to get key bind events to work at all. Should I be binding them to something else, or did I just write it incorrectly?

(Sorry about the wall of code, I made it as short as I could)

from tkinter import *

playerPos=0   
length=9
width=9


class GridTools:

#make a 2d array of Labels
    def __init__(self,root):
        self.grid=[]
        acc=-1# keep track of the number of loops. Will be 0 by the time
        #it's on a button

        for x in range (0,length):
            for y in range(0,width):
                acc+=1
                tile=Label(bg="black",fg="white",text=str(acc))
                self.grid.append(tile)
                tile.grid(row=x,column=y)
        PlayerTile.makePlayer(self.grid)#put player in the grid
    #add movement buttons
    #I still don't understand Lambdas
        moveUp= Button(text="up", command=lambda :PlayerTile.movePlayer(self.grid,"UP"))
        moveUp.grid(row=11, column=11)
        moveDown= Button(text="down", command=lambda :PlayerTile.movePlayer(self.grid,"DOWN"))
        moveDown.grid(row=13, column=11)
        moveLeft= Button(text="left", command=lambda :PlayerTile.movePlayer(self.grid,"LEFT"))
        moveLeft.grid(row=12, column=10)
        moveRight= Button(text="right", command=lambda :PlayerTile.movePlayer(self.grid,"RIGHT"))
        moveRight.grid(row=12, column=12)

    #this doesn't do anything
        moveUp.bind('<Up>',lambda: layerTile.movePlayer(self.grid,"UP"))

    #Manipulate the green player tile
class PlayerTile:
    def makePlayer(grid):
        global playerPos
        grid[playerPos].config(bg="green")

    def movePlayer(grid,direction):
        global playerPos

        if(direction=="UP" and playerPos>8):

            grid[playerPos].config(bg="grey")
            playerPos= playerPos -9
            grid[playerPos].config(bg="green")

        if(direction=="DOWN" and playerPos<(width-1)*length):

            grid[playerPos].config(bg="light blue")
            playerPos= playerPos +9
            grid[playerPos].config(bg="green")

        if(direction=="LEFT" and (playerPos)%length!=0):

            grid[playerPos].config(bg="light pink")
            playerPos= playerPos -1
            grid[playerPos].config(bg="green")

        if(direction=="RIGHT" and (playerPos+1)%length!=0):

            grid[playerPos].config(bg="light yellow")
            playerPos= playerPos +1
            grid[playerPos].config(bg="green")



root=Tk() 
x=GridTools(root)#initialilize the grid using GridTools' init function
root.mainloop()

Upvotes: 0

Views: 3323

Answers (1)

SneakyTurtle
SneakyTurtle

Reputation: 1857

In your line moveUp.bind('<Up>',lambda: layerTile.movePlayer(self.grid,"UP")), you are binding the Up key to the moveUp widget.

In order to have the desired effect you want, you instead need to bind it to root:

root.bind('<Up>', lambda e: layerTile.movePlayer(self.grid,"UP"))

Note that I pass e (event) to the lambda expression. A lambda expression can be thought of as an inline function, where the contents is evaluated whenever it is called, and arguments are passed before the colon.

If you copy this line for each arrow key, then you should get your desired outcome.

Upvotes: 2

Related Questions