类型错误:缺少一个必需的位置参数'event'。

3

我正在制作一个绘画程序,但遇到了这个错误。然而,如果我更改事件的 x/y 的定义位置,同样的错误会出现,但是与不同的子程序有关。

以下是代码:

class paint:
    def __init__(self,root,canvas):
        self.root = root
        self.mouse_press = False #mouse isnt being pressed

        self.canvas = canvas

        self.canvas.bind('<ButtonPress-1>',self.MouseDown) # when left click is pressed / down the subroutine MouseDown is opened 
        self.canvas.bind('<ButtonRelease-1>',self.MouseUp)#when left click is relased open the MouseUp subroutine         
     
    def MouseDown(self,event):
        self.x = event.x
        self.y = event.y

        self.mouse_press = True # mouse is pressed 
        self.poll() #calls the coodinates subroutine 

    def MouseUp(self,event):
        
        self.poll()
        self.mouse_press = False
        self.root.after_cancel(self.after_id)

    def poll(self):

        if self.mouse_press:
 
            canvas.create_oval(self.x,self.y, self.x+10, self.y+10 , fill = '#f6f65a',outline = '#f6f65a')
            self.after_id = self.root.after(10,self.MouseDown)


def colour_pick():
    colour_choose = colorchooser.askcolor()[1] #opens a colour picker and picks the colour
    print(colour_choose)
    return(colour_choose)

我如何调用这个类

p = paint(root,canvas)
root.mainloop()

我经常遇到的错误:
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 839, in callit
    func(*args)
TypeError: paint.MouseDown missing 1 required positional argument: 'event'
3个回答

3
你的函数 MouseDown 需要一个 event 参数,因为你定义它时是这样的:
def MouseDown(self,event):

然而,当您从 after 中调用函数时,并没有传递此参数:
self.after_id = self.root.after(10,self.MouseDown)

MouseDown 使用 event 对象中的数据,因此您需要合成一个具有函数使用属性的对象(例如:.x.y),或者重写 MouseDown 函数以不需要 event 参数。


1
错误的原因已经在Bryan的回答中解释过了。
对于您的情况,绑定事件和就足够了,不需要使用.after()。
class paint:
    def __init__(self, root, canvas):
        self.root = root
        self.canvas = canvas

        self.canvas.bind('<Button-1>', self.mouse_down)
        self.canvas.bind('<B1-Motion>', self.poll)

    def mouse_down(self, event):
        # save initial drag point
        self.x, self.y = event.x, event.y

    def poll(self, event):
        # draw line from last saved point to current point instead of drawing circle
        self.canvas.create_line(self.x, self.y, event.x, event.y, fill='#f6f65a', width=10, capstyle='round')
        # save current point
        self.x, self.y = event.x, event.y

0

你在试图伪造<Motion>时工作过度了。以下是我认为你实际上想要做的事情。

import tkinter as tk


class Canvas(tk.Canvas):
    def __init__(self, master, **kwargs):
        tk.Canvas.__init__(self, master, **{'background':'#000000', 'highlightthickness':0, **kwargs})
        self.bind('<Motion>', self.motion)
    
    #instead of attempting to programmatically toggle up and down states
    def motion(self, e):
        if (e.state & 256) == 256: #if mouse 1 is down
            self.create_oval(e.x, e.y, e.x+10, e.y+10, fill='#f6f65a', outline='#f6f65a') #fill and outline should actually come from your ColorChooser
        

class Root(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.paint = Canvas(self)
        self.paint.pack(expand=True, fill=tk.BOTH)
        

if __name__ == '__main__':
    Root().mainloop()



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接