python-tkinter problem with command in button

0

I have the following code with a form class that calls the componentes.py module that contains some basic functions to generate basic forms.

In principle only the user login and password is created, until then it goes well, but then I created another madulo called verify where I am trying to check in some way user and password, but the problem is that when using command of the button I call the function to check the module verify this does not wait for me to press the "enter" button to perform this function but it runs automatically and as I did not place anything directly triggers the error message. Then it allows me to put username and password but pressing "enter" says that an argument is missing ( TypeError: chequear() missing 1 required positional argument: 'lista' ).

I will appreciate your help because I want to solve this simple exercise that I proposed and it is costing me.

import tkinter as tk
import componentes as cpt
import verificar as vf

""" FORMULARIO DE INGRESO permite accder a la app en si """

class Formularios():

    def __init__(self):

        self.listaCaja=[]
        self.listaBoton=[]
        self.listaEtiqueta=[]
        self.comando=[]

    #----------- VENTANA ACCESO -----------

    def acceso(self):

        lista=("USUARIO:", "CLAVE:")
        lista2=("ENTRAR", "SALIR")

        raiz=tk.Tk()
        raiz.resizable(0, 0)
        raiz.title("Ingreso de Usuarios")

        marcoUno=tk.Frame(raiz, width="200", height="100")
        marcoUno.grid(column=0, row=0) 

        marcoDos=tk.Frame(raiz, width="200", height="50")
        marcoDos.grid(column= 0, row=1)

        #----------- ETIQUETAS mUNO-----------

        for i in range(len(lista)):
            self.listaEtiqueta.append(cpt.crear_E(marcoUno, lista[i]))
            cpt.ordenar(self.listaEtiqueta[i], i, 0, 5)

        #----------- CAJAS TEXTO mUNO-----------

        for i in range(len(lista)):
            self.listaCaja.append(cpt.crear_C(marcoUno, "20"))
            cpt.ordenar(self.listaCaja[i], i, 1, 5, 5)


        #----------- BOTONES mDOS-----------

        vf.chequear(self.listaCaja)
        self.comando=[vf.chequear, quit]



        for i in range(len(lista2)):
            self.listaBoton.append(cpt.crear_B(marcoDos, lista2[i], "10", self.comando[i]))
            cpt.ordenar(self.listaBoton[i], 0, i, 5, 2, "", 1)


        raiz.mainloop()


raiz=Formularios()      
raiz.acceso()
#                       ----componentes.py-----

import tkinter as tk

"""Este módulo está orientado a crear componentes sencillos de un formulario"""

#---------- ORDENAR ELEMENTOS ------------------

def ordenar(obj="", fila=0, col=0, x=0, y=0, coord="", cols=1, rows=1):
    obj.grid(row=fila, column=col,  padx=x, pady=y, sticky=coord, columnspan=cols, rowspan=rows)


#---------- CREAR ELEMENTOS ------------------

def crear_E(contenedor, titulo=""):
    etiqueta=tk.Label(contenedor, text= titulo)
    return etiqueta 


def crear_C(contenedor, ancho="15"):
    caja=tk.Entry(contenedor, width= ancho)
    return caja


def crear_B(contenedor, titulo="", ancho="10", comando=""):
    boton=tk.Button(contenedor, text=titulo, width=ancho, command=comando)
    return boton
    
#                    ----verifica.py-----

from tkinter import messagebox

def chequear(lista):
    if lista[0].get() == 1 and lista[1].get() == 2:
        print("ok") 
    else:
        messagebox.showwarning(title= "Denegado", message= "Su autenticación es Incorrecta")
    
asked by mag55 16.11.2018 в 03:31
source

1 answer

0

Your verify function is executed because you are calling it!

Look, in this line within the Formularios.acceso method:

    #----------- BOTONES mDOS-----------

    vf.chequear(self.listaCaja)   # <---------   AQUI!
    self.comando=[vf.chequear, quit]

You must delete that call, and let Tkinter call that function when the user presses the appropriate button.

But then you will have another problem, and that is that the method you assign to that button using these lines:

    self.comando=[vf.chequear, quit]
    for i in range(len(lista2)):
        self.listaBoton.append(cpt.crear_B(marcoDos, lista2[i], "10", self.comando[i]))
        cpt.ordenar(self.listaBoton[i], 0, i, 5, 2, "", 1)

It will be the vf.chequear method. If we look at the code of that method (in the file verificar.py ) two problems are observed:

def chequear(lista):
    if lista[0].get() == 1 and lista[1].get() == 2:
        print("ok") 
    else:
        messagebox.showwarning(title= "Denegado", message= "Su autenticación es Incorrecta")

The first is that you are comparing the contents of the text boxes with the numbers 1 and 2 . This will always be false, since what those boxes contain are strings and not numbers. You must use "1" and "2" instead.

But the most serious problem is that this function expects a parameter ( lista ), but there is no way to pass parameters to the commands of the buttons, since who invokes those commands is Tkinter as we saw before how is it going to Tkinter know what parameters to pass?

The usual practice is to use as command a method of the class the button is in, so that this method has access to the attributes of the class, such as self.listaCaja and can extract from there what you need.

So you can change the assignment of commands to buttons to use:

    self.comando=[self.chequear, quit]
    for i in range(len(lista2)):
        self.listaBoton.append(cpt.crear_B(marcoDos, lista2[i], "10", self.comando[i]))
        cpt.ordenar(self.listaBoton[i], 0, i, 5, 2, "", 1)

And write a Formularios.chequear() method that would already have access to self.listaCaja and could be passed as a parameter to vf.chequear :

class Formularios():
    # ... omito el resto

    def chequear(self):
        return vf.chequear(self.listaCaja)
    
answered by 16.11.2018 / 10:13
source