0

my code seems to run fine with the brown square appearing in the blank window until I try and press one of the keys, when I do that nothing happens apart from an error message appearing. Any ideas?

from tkinter import *

x, y, a, b = 50, 50, 100, 100
d = None

vel_dic = {
    "Left": ("left", -4, 0),
    "Right": ("right", 4, 0),
    "Down": ("down", 0, 4),
    "Up": ("up", 0, -4)}
class Sprite:
    def __init__(self):
        self.move
        self.x, self.y, self.a, self.b = 50, 50, 100, 100
        self.d = 0
        self.canvas = Canvas(tk, height = 600, width = 600)
        self.canvas.grid(row=0, column=0, sticky = W)
        self.coord = [self.x, self.y, self.a, self.b]
        self.shape = self.canvas.create_rectangle(*self.coord, outline = "#cc9900", fill = "#cc9900")
    def move():
        if self.direction != 0:
            self.canvas.move(self.rect, self.xv, self.yv)
        tk.after(33, move)
    def on_keypress(event):
        self.direction, self.xv, self.yv = vel_dic[event.keysym]
    def on_keyrelease(event):
        self.direction = 0 

tk = Tk()
tk.geometry("600x600")

sprite1 = Sprite()

tk.bind_all('<KeyPress>', sprite1.on_keypress)
tk.bind_all('<KeyRelease>', sprite1.on_keyrelease)

Error message when I press the right arrow key:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\robsa\AppData\Local\Programs\Python\Python36-32\lib\idlelib\run.py", line 137, in main
    seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  File "C:\Users\robsa\AppData\Local\Programs\Python\Python36-32\lib\queue.py", line 172, in get
    raise Empty
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\robsa\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
TypeError: on_keypress() takes 1 positional argument but 2 were given
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\robsa\AppData\Local\Programs\Python\Python36-32\lib\idlelib\run.py", line 137, in main
    seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  File "C:\Users\robsa\AppData\Local\Programs\Python\Python36-32\lib\queue.py", line 172, in get
    raise Empty
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\robsa\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
TypeError: on_keyrelease() takes 1 positional argument but 2 were given
Rob.S
  • 23
  • 1
  • 4

1 Answers1

1

When calling to function inside an object, self (the instance of the object) is sent as a first argument. You can undo that with some methods, staticmethod as the most common one, but that is not what you look for in that case.

The error you get indicates the interpreter sent this self parameter and the regular event parameter, but your method gets only one parameter, and can not handle them.

Make sure all your functions gets self (or any name you choose like inst) as a first parameter in addition to the other parameters:

def on_keyrelease(self, event):

Same goes for move and on_keypress.

Uriel
  • 15,579
  • 6
  • 25
  • 46
  • Thanks very much, it removed the error. However the code still doesn't move the square. Can you see the problem? – Rob.S Jan 14 '17 at 18:26
  • Your class does not inherit a tkinter `Frame` or `Widget`, and the properties names are broken. Take a look at this thread for oop tkinter - http://stackoverflow.com/a/17470842/6575931 – Uriel Jan 14 '17 at 18:29
  • At no point do you ever actually call the ``move()`` method, so of course it doesn't move. You're also not consistently naming your variables - ``self.d`` vs. ``self.direction``, ``self.shape`` v.s ``self.rect``. – jasonharper Jan 14 '17 at 18:31