Search code examples
pythontkinterpyautogui

Does pyautogui.keydown() not register as an event in python's bind() function?


I am making a game in which you dodge falling object by using the tkinter library. In my code, I am trying to make an object fall by binding a canvas.move() function with pressing the down arrow key, then using pyautogui to hold down the key. Here is my code:

from tkinter import *
from random import randint
import pyautogui


class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)

        self.master = master
        self.initWindow()

    def initWindow(self):
        self.master.title('Dodger')
        self.pack(fill=BOTH, expand=1)
        self.master.geometry('600x800')
        self.master.config(bg='black')

        menu = Menu(self.master)
        self.master.config(menu=menu)

        def clientExit():
            exit()

        file = Menu(menu)
        file.add_command(label='Exit', command=clientExit)
        file.add_command(label='Start', command=self.game)

        menu.add_cascade(label='File', menu=file)

    def game(self):
        canvas = Canvas(self.master, width='600', height='800', borderwidth='0', highlightthickness='0')
        canvas.pack()
        canvas.create_rectangle(0, 0, 600, 800, fill='black', outline='black')

        character = canvas.create_rectangle(270, 730, 330, 760, fill='magenta', outline='cyan', width='2')

        def left(event):
            cord = canvas.coords(character)
            if not cord[0] <= 5:
                canvas.move(character, -10, 0)

        def right(event):
            cord = canvas.coords(character)
            if not cord[2] >= 595:
                canvas.move(character, 10, 0)

        self.master.bind('<Left>', left)
        self.master.bind('<Right>', right)

        class variables:
            sizeMin = 10
            sizeMax = 80

            y = 10
            minX = 5
            maxX = 545

        def createShape():
            size = randint(variables.sizeMin, variables.sizeMax)

            x = randint(variables.minX, variables.maxX)
            topLeft = [x, variables.y]
            bottomRight = [x + size, variables.y + size]

            shape = canvas.create_rectangle(topLeft[0], topLeft[1], bottomRight[0], bottomRight[1],
                                            fill='red', outline='red')
            return shape

        def moveShape(event):
            cord = canvas.coords(x)
            if cord[1] != 800:
                canvas.move(x, 0, 10)

        x = createShape()

        self.master.bind('<Down>', moveShape)
        pyautogui.keyDown('down')


root = Tk()
app = Window(root)
app.mainloop()

As you can see, at the bottom of the class, I binded the down arrow key and moving a shape down. However, the pyautogui does not work; the object does not move down unless I manually press the down arrow key. Am I forgetting something or is pyautogui not compatible with bind()? I know there are more efficient ways to move the object down, however with all the methods I have tried, none show the actual movement of the object heading down the screen; they just show the object being re-created in another position. Please let me know how I can fix this.


Solution

  • I wouldn't bother with it. Maybe it misses the _all argument. Try to simply bind canvas.move() function to a canvas.bind_all()