Tkinter error on a label object

Asked

Viewed 95 times

-1

First good afternoon friends, I am developing a POO application in python and my object returned the following error:

  File "codigo_principal.py", line 37, in <module>
    menu=Autenticar(["Roboto",10],"LavenderBlush",[1,40],('400x150'),"MENU",True)
  File "/home/bart/teste/janela.py", line 29, in __init__
    self.nome=Criar_Label(self.root,"NOME",xy[0],xy[1],fonte,fundo)
  File "/home/bart/teste/criar_widgets.py", line 6, in __init__
    self.label=Label(root)
  File "/usr/lib/python3.6/tkinter/__init__.py", line 2766, in __init__
    Widget.__init__(self, master, 'label', cnf, kw)
  File "/usr/lib/python3.6/tkinter/__init__.py", line 2299, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: can't invoke "label" command: application has been destroyed

I searched the Python documentation, more specifically Tkinter and realized that this error usually occurs when there are window problems when destroying the previous one to create a new one. However in my case I’m not trying to do it, my code so far only has a window!

Follow the files that form the code: 1-main code.py

from janela import *
menu=Autenticar(["Roboto",10],"LavenderBlush",[1,40],'400x150'),"MENU",True)

2-py

from tkinter import *
from criar_widgets import *

class Janelas:
   def __init__(self,fonte,fundo,xy,tela,titulo,original):
     #Caso seja a janela mãe
     if original:
          #Esta é a variável da janela mãe
          self.root = Tk()
     #Caso seja uma janela filha

     else:
          #Esta é a variável da janela filha
          self.root= Toplevel()

     #Esta é a cor de fundo da janela
     self.root["bg"]=fundo
     #Este é o título
     self.titulo=Criar_Label_Titulo(self.root,titulo,fonte,fundo)
     #Este é o tamanho da janela
     self.root.geometry(tela)
     self.root.mainloop()

class Autenticar(Janelas):
    def __init__(self,fonte,fundo,xy,tela,titulo,original):

        super().__init__(fonte,fundo,xy,tela,titulo,original)

        self.nome=Criar_Label(self.root,"NOME",xy[0],xy[1],fonte,fundo)
        self.entrar_nome=Criar_Entry(self.root,xy[0]+50,xy[1],fonte,fundo,False)  

        self.senha=Criar_Label(self.root,"SENHA",xy[0],xy[1]+30,fonte,fundo)
        self.entrar_senha=Criar_Entry(self.root,xy[0]+50,xy[1]+30,fonte,fundo,True)

        self.botao=Criar_Button(self.root,"INSERIR NOME",fonte,fundo,lambda:login(self.root,usuario,senha))

    def login(self,usuario,senha):
        if usuario == "" and senha == "":
           pass
            #self.root.destroy()

3-create widgets.py

from tkinter import *

class Criar_Label:
    def __init__(self,root,texto,abcissa,ordenada,fonte,fundo):
         self.label=Label(root)
         self.label["text"]=texto
         self.label["font"]=fonte
         self.label["bg"]=fundo
         self.label.place(x=abcissa,y=ordenada)

#Será que deveríamos fazer polimorfismo aqui e fazer da classe Criar_Label a classe mãe?
class Criar_Label_Titulo:
    def __init__(self,root2,texto,fonte,fundo):
         self.titulo=Label(root2)
         self.titulo["text"]=texto
         self.titulo["font"]=fonte
         self.titulo["bg"]=fundo
         self.titulo.pack()

class Criar_Entry:
    def __init__(self,root2,abcissa,ordenada,fonte,fundo,segredo):
         self.entry=Entry(root2,font=fonte)
         self.entry.place(x=abcissa,y=ordenada)
         if segredo:
             self.entry["show"]="*"

class Criar_Button:
    def __init__(self,root2,texto,fonte,fundo,comando):
         self.button=Button(root2)
         self.button["text"]=texto
         self.button["font"]=fonte
         self.button["bg"]=fundo
         self.button["command"]=comando

         self.button.pack(side=BOTTOM)

Until you open the window and put a widget label,but hangs and when closes gives the error. The documentation I have studied to come to the conclusion that it is an error to open or close a window are the following pages:

1- The stack overflow page itself

https://stackoverflow.com/questions/29655219/whats-the-difference-between-tkinters-tk-and-toplevel-classes

2- O Reddit

https://www.reddit.com/r/learnpython/comments/cx4lu9/cant_invoke_label_error_using_tkinter_on_python_36/

I do not know if I misunderstood the documentation or not, but the error exists and I do not know correct it.

Grateful

  • apparently the label does not have a reference in memory, so it is destroyed, I believe you can simplify your code, after you fix the reference label, will have the same problem with entry

  • I got lost now, I tested all classes, and they work well, only the error when it calls the authenticate class, I have no idea of pq

  • So... I’m in the same... I can understand making a mistake there, but I don’t know the reason for this mistake in esoecific (since it is a window change error)

1 answer

1


solved the problem by reversing the inheritance

in your code you create

class Janelas
class Autenticar(Janelas)

if you reverse to

class Autenticar
class Janelas(Autenticar)

and correct the call of super(), the code runs showing the label and entry smoothly

Here’s how I organize my apps, you can see that the settings are in other classes

from gui import GUI
from gerador import Gerador
from conf import Setup
from mapas import ZipA

class App(GUI, Gerador, Setup, ZipA):
    VER = 'Maio/2019'

app = App()

GUI is the class that takes care of the design

Setup is the class that connects functionality with design


seen as this the code in git, I thought in a slightly different media

class Autenticar:
    def __init__(self,fonte,fundo,xy,tela,titulo,original):
        self.nome=Criar_Label(self.root,"NOME",xy[0],xy[1],fonte,fundo)
        self.entrar_nome=Criar_Entry(self.root,xy[0]+50,xy[1],fonte,fundo,False)  

        self.senha=Criar_Label(self.root,"SENHA",xy[0],xy[1]+30,fonte,fundo)
        self.entrar_senha=Criar_Entry(self.root,xy[0]+50,xy[1]+30,fonte,fundo,True)

        self.botao=Criar_Button(self.root,"INSERIR NOME",fonte,fundo,lambda:login(self.root,usuario,senha))

    def login(self,usuario,senha):
        if usuario == "" and senha == "": 
           pass
            #self.root.destroy()

class Janelas(Autenticar):
   def __init__(self,fonte,fundo,xy,tela,titulo,original):
     if original:
          self.root = Tk()

     else:
          self.root= Toplevel()
     super().__init__(fonte,fundo,xy,tela,titulo,original)

     self.root["bg"]=fundo
     self.titulo=Criar_Label_Titulo(self.root,titulo,fonte,fundo)
     self.root.geometry(tela)
     self.root.mainloop()


menu=Janelas(["Roboto",10],"LavenderBlush",[1,40],'400x150',"MENU",True)
  • There is a problem in doing so, which in this case is precisely the solution... I created the window class so that I can make multiple windows more easily through the mother class. This class in question has features that all windows in my code would have (like the background color, the font or the Label title). The fact is, if I reverse it, I wouldn’t be facilitating it, but making it harder. But thank you so much for the warning to reverse inheritance, now I know that the problem is not syntax.

  • it is still possible to have the result you want, and reduce the class you made to create Labels and the elements, they themselves are not making any use of the capabilities of a class

  • I’ll do what you told me then, if it really works out I’ll come back and give you the feedback.

  • it will work, I make applications where there is an empty class that inherits all the configurations of other classes, this includes functionality and design

  • What you told me worked out well, maybe it’s even simpler if you do it this way. I’ll even make the code available on github if other people have this problem. But thank you very much. Here’s the git link to the solution you proposed: https://github.com/bhartolomeu/test

  • my solution was to change the order of the classes, change who inherits from whom, and also change the super of place, apart from these changes that are almost exclusive of the class header the rest remains unchanged

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.