0

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()
1
  • I can't actually get the binding to run at all, even with your changes. I also tried adding event to the method parameters, and nothing is happening. I also tried using the debugger, which didn't work since tkinter seems to be outside its scope. Commented Oct 8, 2017 at 7:54

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.