name is not defined - name/variable undefined, Tkinter and slite3 help

Asked

Viewed 344 times

0

I’m starting to study sqlite3 in Marra, and this being difficult, but I already got a few things, the problem is that when compiling the program appears the following error:

"name 'adic' is not defined".

Follows the code:

from tkinter import*
import sqlite3

class Principal:
    def __init__(self):
        janela_principal = Tk()
        janela_principal.geometry("400x400+50+50")
        #janela_principal.overrideredirect(True)

        lb0 = Label(janela_principal)
        lb0.grid(row=0, column=0, padx=13)


        lb1 = Label(janela_principal, text="Digite um número:")
        lb1.grid(row=1, column=1, sticky=E)
        digite_numero = Entry(janela_principal, width=35)
        digite_numero.grid(row=1, column=2, sticky=W)
        separador = Frame(janela_principal, height=2, bd=3, relief=SUNKEN, width=340)
        separador.grid(row=2, column=1, columnspan=2)

        lb2 = Label(janela_principal, text="Assunto:")
        lb2.grid(row=3, column=1, sticky=E)
        digite_assunto = Entry(janela_principal, width=35)
        digite_assunto.grid(row=3, column=2, sticky=W)

        separador = Frame(janela_principal, height=2, bd=3, relief=SUNKEN, width=340)
        separador.grid(row=4, column=1, columnspan=2)

        add = Button(janela_principal, text="ADICIONAR NOME", relief=SOLID, border=1, foreground="BLUE", command=adic)
        add.grid(row=5, column=2, columnspan=2, sticky=W)
        apagar = Button(janela_principal, text="APAGAR NOME", relief=SOLID, border=1, foreground="RED", command=apag)
        apagar.grid(row=5, column=2, sticky=E)


        lb3 = Label(janela_principal)
        lb3.grid(row=6, column=0)


        rolagem = Scrollbar(janela_principal)
        rolagem.grid(row=7, column=2, sticky=N+S+E)

        caixa_exibição = Listbox(janela_principal, relief=SOLID, border=1, width=45, height=15, font=("Gentium Basic", 11))
        caixa_exibição.grid(row=7, column=1, columnspan=2, sticky=W)


        #for i in range(100):
        #    caixa_exibição.insert(END, i)

        # attach listbox to scrollbar
        caixa_exibição.config(yscrollcommand=rolagem.set)
        rolagem.config(command=caixa_exibição.yview)



        #Banco
        conectar = sqlite3.connect("numeros.db")
        cursor = conectar.cursor()
        cursor.execute("CREATE TABLE IF NOT EXISTS nomes(numeros TEXT, assunto TEXT)")
        conectar.commit()
        lista = cursor.execute("SELECT * FROM nomes")
        for i in lista:
            caixa_exibição.insert(END, i)

    def adic():
        numerosx = digite_numero.get()
        assuntox = digite_assunto.get()
        cursor.execute("INSERT INTO nomes values(?, ?)", (numerosx, assuntox))
        conectar.commit()
        caixa_exibição.insert(END, numerosx)
        caixa_exibição.insert(END, assuntox)

    def apag():
        numerosy = str(caixa_exibição.get(ACTIVE))[3:-3]
        assuntoy = str(caixa_exibição.get(ACTIVE))[3:-3]

        cursor.execute("DELETE FROM nomes WHERE name=?, ?", (numerosy, assuntoy))
        conectar.commit()
        caixa_exibição.delete(ANCHOR)





        janela_principal.mainloop()

Principal()
  • How so? You can give me an example?

  • 1

    Your code is quite confusing: the functions adic and apag are indented, as if they were class methods Principal, but were defined as functions without the parameter self. Should they be instance methods, class methods or functions outside the class? Also, within the function adic you use the object digite_numero which was defined in __init__ and therefore does not exist within this function. Should this object be an instance field? Note that this is not even related to Sqlite yet.

2 answers

4

In this case it’s quite simple: you’re making a class, not with loose functions - so by declaring the command=..., instead of command=adic, you must use command=self.adic.

And, of course, since they are methods, put the parâtro self in their definition.

If you want to use only as a function, that’s fine - in this case just remove them from the class body (indenting them in the zero column), then you don’t need the self.adic nor the parameter self, but then you also can’t share variables between your functions.

The advantage of doing everything as a class (without inheriting any Tkinter class, exactly as it is in your code), is that you can define variables in the __init__ which will be class attributes - then, its function adic need to access the caixa_exibicao for example - she can do this, if so much on the __init__ how much in the method you always use self.caixa_exibicao. Add the self. in all variables you need to access from all functions of your code.

(the self. valley to the cursor and all the other variables you share, of course).

  • jsbueno My thanks so much for the excellent explanation, I wish you success in your career, thanks.

-1


By indications of professionals, I always recommend to define the methods before the rest of the program (although it is not necessary, do as you wish).

Because it is using classes, it is necessary to use self. in order to access the variables within the class, for this reason "adic" appeared as "undefined", as it was outside its scope.

Follow the code showing some applications in this sense, it is not necessarily mandatory to use everything as I used:

from tkinter import*
import sqlite3

class Principal:
    def adic(self): #Métodos antes, com o paramentro self para receber variáveis do __init__
        numerosx = self.digite_numero.get() #Por ser uma variável utilizada apenas dentro dessa função, não existe a necessidade do self.
        assuntox = self.digite_assunto.get()
        self.cursor.execute("INSERT INTO nomes values(?, ?)", (numerosx, assuntox)) #Cursor é uma variável do método __init__, por esse motivo, precisamos utilizar self. para acessá-la
        self.conectar.commit()
        self.caixa_exibição.insert(END, numerosx+" "+assuntox) #Aqui você irá inserir: 'numerox assuntox', do modo como estava fazendo, você inseria um por vez, fazendo com que um ficasse abaixo do outro
        #self.caixa_exibição.insert(END, assuntox)

    def apag(self):
        selecionada = str(self.caixa_exibição.get(ACTIVE)).replace('(','').replace(')','').replace("'","").split(',') #Coleta a linha selecionada, e por ser uma string, eu faço o tratamento da linha, removendo varias coisas como "(')". Além disso, estou fazendo um array, separando os elementos por ",".
        try:
            self.numerosy = selecionada[0]
            self.assuntoy = selecionada[1][1:]
        except:
            selecionada = str(self.caixa_exibição.get(ACTIVE)).split(" ")
            self.numerosy = selecionada[0]
            self.assuntoy = selecionada[1]

        self.cursor.execute("DELETE FROM nomes WHERE numeros='"+self.numerosy+"' AND assunto = '"+self.assuntoy+"'") #Corrigi a Query
        self.conectar.commit()
        self.caixa_exibição.delete(ANCHOR)
    def __init__(self):
        janela_principal = Tk()
        janela_principal.geometry("400x400+50+50")
        #janela_principal.overrideredirect(True)

        lb0 = Label(janela_principal)
        lb0.grid(row=0, column=0, padx=13)


        lb1 = Label(janela_principal, text="Digite um número:")
        lb1.grid(row=1, column=1, sticky=E)
        self.digite_numero = Entry(janela_principal, width=35)
        self.digite_numero.grid(row=1, column=2, sticky=W)
        separador = Frame(janela_principal, height=2, bd=3, relief=SUNKEN, width=340)
        separador.grid(row=2, column=1, columnspan=2)

        lb2 = Label(janela_principal, text="Assunto:")
        lb2.grid(row=3, column=1, sticky=E)
        self.digite_assunto = Entry(janela_principal, width=35) #Usar self. para tornar a variável acessível
        self.digite_assunto.grid(row=3, column=2, sticky=W)

        separador = Frame(janela_principal, height=2, bd=3, relief=SUNKEN, width=340)
        separador.grid(row=4, column=1, columnspan=2)

        add = Button(janela_principal, text="ADICIONAR NOME", relief=SOLID, border=1, foreground="BLUE", command=self.adic)
        add.grid(row=5, column=2, columnspan=2, sticky=W)
        apagar = Button(janela_principal, text="APAGAR NOME", relief=SOLID, border=1, foreground="RED", command=self.apag)
        apagar.grid(row=5, column=2, sticky=E)


        lb3 = Label(janela_principal)
        lb3.grid(row=6, column=0)


        rolagem = Scrollbar(janela_principal)
        rolagem.grid(row=7, column=2, sticky=N+S+E)

        self.caixa_exibição = Listbox(janela_principal, relief=SOLID, border=1, width=45, height=15, font=("Gentium Basic", 11))
        self.caixa_exibição.grid(row=7, column=1, columnspan=2, sticky=W)


        #for i in range(100):
        #    caixa_exibição.insert(END, i)

        # attach listbox to scrollbar
        self.caixa_exibição.config(yscrollcommand=rolagem.set)
        rolagem.config(command=self.caixa_exibição.yview)



        #Banco
        self.conectar = sqlite3.connect("numeros.db")
        self.cursor = self.conectar.cursor()
        self.cursor.execute("CREATE TABLE IF NOT EXISTS nomes(numeros TEXT, assunto TEXT)")
        self.conectar.commit()
        self.lista = self.cursor.execute("SELECT * FROM nomes")
        for i in self.lista:
            self.caixa_exibição.insert(END, i)


        janela_principal.mainloop()

Principal()
  • 1

    A detail: the order that is defined the methods does not matter, so it will make no difference to define adic before __init__.

  • I would be more comfortable, if you don’t know the language well, to test what you did, before responding with a code of more than 30, 40 lines made in the kick.

  • "By indications of professionals, I always state to define the methods before the rest of the program " here you have another professional not indicating that. In Python, the recommendation is to define the __init__ before the other methods.

  • @Nathanschroeder Dear thank you so much, I managed to complete my project. In a while I will do a larger project, hopefully next time if I get any doubt you can help me again. : D, Thank You Man

  • @Nathanschroeder sorry to be annoying, but I need a detail. It’s because I’m going to do something bigger later, so I need to know at least the basis, come on. When we add the item in the row and delete everything is ok, just as I wanted, only after the item is saved, and the program runs for the second time column 1 and 2 comes with keys, for example: '{ 1819 - P1/2018} {Information}', respectively columns 1 and 2, both with { }, how do I fix this?

  • @Victors' If you insert '1' and 'test' it does not happen, if you just press add, with empty fields, it happens, I believe that are characters in which the DB does not read correctly, I think you should do a search about it.

  • Thanks again @Nathanschroeder

Show 2 more comments

Browser other questions tagged

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