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)