1

I was looking to do a popup widget in tkinter where the user can input some data. But while I was testing I came up with the following error:

  File "returnWeeksGUI_v1.py", line 363, in __init__
    self.content = program.popup("Add_label")
  File "returnWeeksGUI_v1.py", line 296, in popup
    self.w=popupWindow(self.master,popup_type)
  File "returnWeeksGUI_v1.py", line 42, in __init__
    self.bu=tk.Button(top,text='Ok',command=self.cleanup(win_type))
  File "C:\Users\Fernanda\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2369, in __init__
    Widget.__init__(self, master, 'button', cnf, kw)
  File "C:\Users\Fernanda\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2299, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: bad window path name ".!toplevel"

It has been 3 days of debugging and editing the code, but still hadn't found the appropiate solution.


The code

I have some imports and variables:

import tkinter as tk

models = {
    "text":["TXT",50,50],
    "DD":["DD",50,50],
    "MM":["MM",50,50],
    "AA":["AA",50,50],
    "MC":["MC",50,50],
    "DP":["DP",50,50],  
    }

I have a tkinter class:

class App(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master = master

        #This class has some variables:
        self.pu= program.popup("Add_label")

    def popup(self,popup_type):
            self.w=popupWindow(self.master,popup_type)
            self.master.wait_window(self.w.top)

I also have a popup code gotten from a question in StackOverflow, which I modified for my purposes. It shows up some radiobuttons/entries that the user has to complete/select.

class popupWindow(object):
    def __init__(self,master,win_type):
        top=self.top=tk.Toplevel(master)
        if str(win_type) == "Add_label":
            """
            Here goes a large piece of code that is irrelevant.  
            """
            # Until I have this set of statements which break the program.
            self.bu=tk.Button(top,text='Ok',command=self.cleanup(win_type))
            self.bu.pack()

        elif str(win_type) == "Add_box":
            #...
            self.bu=tk.Button(top,text='Ok',command=self.cleanup(win_type))
            self.bu.pack()

        elif str(win_type) == "Delete_label":
            #...
            self.bu=tk.Button(top,text='Ok',command=self.cleanup(win_type))
            self.bu.pack()

        elif str(win_type) == "Delete_box": 
            #...
            self.bu=tk.Button(top,text='Ok',command=self.cleanup(win_type))
            self.bu.pack()

    def cleanup(self,win_type):
        #...
        # At the end, a destroy method is called.
        self.top.destroy()

The instance is like this:

root = tk.Tk()
program = App(root)
program.mainloop()

The popup is not triggered by a variable in the __init__() function. In fact it shows up when a certain button is pressed. However, I replaced it here with a variable instead, because it would be easier to analyze. The button that triggers the popup is fine. I've checked it before.


I would be grateful if someone could help. Thanks.

  • You are calling `self.cleanup(win_type)` *right now*, during the creation of your button, thus destroying the very window you're trying to add the button to. One solution would be to write it as `command=lambda: self.cleanup(win_type)`, so that the call is deferred until the button is actually clicked. – jasonharper Jan 29 '19 at 20:30
  • Thanks @jasonharper! The error doesn't show up anymore!. Now it drops another one: `AttributeError: 'popupWindow' object has no attribute 'value'`. But I should be able to deal with that! – Brianprokpo456 Jan 29 '19 at 21:13
  • @Brianprokpo456: Your `class popupWindow` has indeed not attribute `'value'`. So **how** could you deal with it? – stovfl Jan 30 '19 at 11:46
  • That's part of the long code not shown. It has attribute "value". I just didn't put it in the question because I was looking to fix the other error – Brianprokpo456 Jan 30 '19 at 13:51
  • @jasonharper You have answered me on the comments, consider adding an official answer with same/similar content, so I can accept it! – Brianprokpo456 Mar 01 '19 at 19:19

1 Answers1

1

You are calling self.cleanup(win_type) right now, during the creation of your button, thus destroying the very window you're trying to add the button to. One solution would be to write it as command=lambda: self.cleanup(win_type), so that the call is deferred until the button is actually clicked. – jasonharper's answer from comments