Search code examples
pythontkintertoplevel

Passing 3 arguments but trackback says I am passing 4


I have been trying to find the problem here for hours. From what I can find online people are actually passing more arguments than they think for all the post I can find related to this TypeError. For some reason this problem seams to only happen when I am creating a class that inherits from Toplevel.

Tackback:

Exception in Tkinter callback

Traceback (most recent call last):
  File "C:\Program Files\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Makin Bacon\workspace\stuff\MINT-master\test3.py", line 12, in fake_error
    topErrorWindow(self, message, detail)
  File "C:\Users\Makin Bacon\workspace\stuff\MINT-master\test3.py", line 17, in __init__
    tk.Toplevel.__init__(self, master, message, detail)
TypeError: __init__() takes from 1 to 3 positional arguments but 4 were given

I even tried to send my arguments to a dummy function that just prints all the arguments and it only printed 3 arguments.

Here is the code I used to test to see what arguments were being passed.

import tkinter as tk

class MintApp(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        tk.Button(self, text="test error", command=self.fake_error).pack()

    def fake_error(self):
        message = "test"
        detail = "test detail"
        topErrorWindow(self, message, detail)

def topErrorWindow(*items):
        for item in items:
            print("TEST:  ", item)

if __name__ == "__main__":
    App = MintApp()
    App.mainloop()

Here are the results:

TEST:   .
TEST:   test
TEST:   test detail

Now I do not know for sure why I am getting a . for the argument self and I am thinking this might be part of the problem but I cannot find any related issues online.

Here is my code that in my mind should create a top level window with a simple label. Instead I get the trackback error listed above.

import tkinter as tk

class MintApp(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        tk.Button(self, text="test error", command=self.fake_error).pack()

    def fake_error(self):
        message = "test"
        detail = "test detail"
        topErrorWindow(self, message, detail)


class topErrorWindow(tk.Toplevel):
    def __init__(self, master, message, detail):
        tk.Toplevel.__init__(self, master, message, detail)
        tk.Label(self, text = "{}, {}".format(message, detail)).grid(row=0, column=0, sticky="nsew")        

if __name__ == "__main__":
    App = MintApp()
    App.mainloop()

Solution

  • When you do this:

    tk.Toplevel.__init__(self, master, message, detail)
    

    You are passing four arguments to __init__: self, master, message, detail. However, as the error clearly states, Toplevel.__init__ takes from one to three arguments.

    I don't know what you expect the tkinter Toplevel class to do with message and detail, but they don't map to any of the arguments of a Toplevel.

    The solution is to not pass the useless arguments to the superclass constructor since they have meaning to your subclass but not to the superclass:

    tk.Toplevel.__init__(self, master)