Python 3.x _tkinter.TclError: неверное имя пути к окну .!toplevel

Я хотел сделать всплывающий виджет в tkinter, где пользователь может вводить некоторые данные. Но пока я тестировал, я столкнулся со следующей ошибкой:

  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"

Прошло 3 дня отладки и редактирования кода, но подходящего решения так и не нашел.


Код

У меня есть импорт и переменные:

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],  
    }

У меня есть класс tkinter:

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)

У меня также есть всплывающий код, полученный из вопроса в StackOverflow, который я модифицировал для своих целей. Он показывает некоторые радиокнопки/записи, которые пользователь должен заполнить/выбрать.

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()

Экземпляр такой:

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

Всплывающее окно не вызывается переменной в функции __init__(). На самом деле он появляется, когда нажимается определенная кнопка. Однако вместо этого я заменил ее здесь переменной, потому что ее было бы легче анализировать. Кнопка, которая вызывает всплывающее окно, в порядке. Я проверял это раньше.


Буду признателен, если кто-то сможет помочь. Спасибо.


person Brianprokpo456    schedule 29.01.2019    source источник
comment
Вы вызываете self.cleanup(win_type) прямо сейчас во время создания кнопки, тем самым разрушая само окно, в которое пытаетесь добавить кнопку. Одним из решений было бы записать его как command=lambda: self.cleanup(win_type), чтобы вызов откладывался до тех пор, пока кнопка не будет фактически нажата.   -  person jasonharper    schedule 29.01.2019
comment
Спасибо @jasonharper! Ошибка больше не появляется! Теперь выпадает еще один: AttributeError: 'popupWindow' object has no attribute 'value'. Но я должен быть в состоянии справиться с этим!   -  person Brianprokpo456    schedule 30.01.2019
comment
@Brianprokpo456: Ваш class popupWindow действительно не имеет атрибута 'value'. Итак, как с этим справиться?   -  person stovfl    schedule 30.01.2019
comment
Это часть длинного кода, которая не показана. Он имеет значение атрибута. Я просто не указал это в вопросе, потому что хотел исправить другую ошибку.   -  person Brianprokpo456    schedule 30.01.2019
comment
@jasonharper Вы ответили мне в комментариях, рассмотрите возможность добавления официального ответа с таким же / похожим содержанием, чтобы я мог его принять!   -  person Brianprokpo456    schedule 01.03.2019


Ответы (1)


Вы вызываете self.cleanup(win_type) прямо сейчас, во время создания вашей кнопки, тем самым уничтожая то самое окно, в которое вы пытаетесь добавить кнопку. Одним из решений было бы записать его как command=lambda: self.cleanup(win_type), чтобы вызов откладывался до фактического нажатия кнопки. — ответ Джейсона Харпера из комментариев

person Zbyšek Zapadlík    schedule 28.10.2019