Home > Back-end >  How can I fix < TypeError: paint() missing 2 required positional arguments: 'event' and
How can I fix < TypeError: paint() missing 2 required positional arguments: 'event' and

Time:01-24

I'm trying to create a window, which can draw some circles. Using the code below:

from tkinter import *
from tkinter import Tk
from tkinter import Canvas as c

window = Tk()
window.configure(background = "grey")
window.title("Canvas - Draw Shapes")

f_top = Frame(window)
f_bot = Frame(window)
f_top.pack()
f_bot.pack()

# elements
button_1 = Button(f_bot, text='Левая кнопка')
button_2 = Button(f_bot, text='Правая кнопка')
button_1.pack(side=LEFT)
button_2.pack(side=LEFT)

# setting up the canvas
canvas = Canvas(f_top, width=500, height=300, bg = "white")
canvas.pack(expand = YES, fill = BOTH)

def paint(event, window):
    x1, y1 = ( event.x - 4 ), ( event.y - 4 )
    x2, y2 = ( event.x   4 ), ( event.y   4 )
    window.create_oval( x1, y1, x2, y2, fill = black )

canvas.bind('<B1-Motion>', paint())
window.mainloop()

This code returns

TypeError: paint() missing 2 required positional arguments: 'event' and 'window'

I've tried to use self and 'event' and some others as the first argument and 'window', 'canvas' as the second.

CodePudding user response:

You should be able to remove the window argument since window is accessible in the global scope

def paint(event):
    x1, y1 = (event.x - 4), (event.y - 4)
    x2, y2 = (event.x   4), (event.y   4)
    window.create_oval(x1, y1, x2, y2, fill='black')

The other issue is that your event binding is set up incorrectly. It should be: ('<B1-Motion>', paint) (note the lack of () after the function name). This should pass the event to paint automatically.

Essentially what was happening is that when you wrote canvas.bind('<B1-Motion>', paint()), you were calling paint() with 0 arguments, and (as originally written), it expected 2 arguments. By removing the parenthesis, you're no longer calling the function needlessly. Instead, you're assigning it as the callback for the event binding.

CodePudding user response:

This is the problem:

canvas.bind('<B1-Motion>', paint())

Because paint() has the parentheses, it is being called right now, which isn't what you want.

The purpose of canvas.bind() is to pass in a function which will be called later, in response to some event.

So, the fix is probably to just pass the function name:

canvas.bind('<B1-Motion>', paint)
  • Related