Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Problema en el orden en el cual se muestran los mensajes de error al validar campos
#1
Hola.
Tengo un problema al mostrar los mensajes de error al efectuar la validacion de los campos de entrada en una ventana Tkinter.
Consiste en que muestra primero el mensaje de error del campo siguiente al que estoy validando y despues de pulsar <Aceptar> es que muestra el mensaje correcto.

He hecho muchas pruebas con "key", "focusout" y "all" en la propiedad "validate" del campo Entry. Todo parece indicar que al saltar de un campo al siguiente, se activa el "focusout" del campo siguiente antes que el "focusout" del campo que estoy validando. Quisiera poder controlar esto para que muestre solo el mensaje que corresponde al campo que esta validando y que haga esto cuando sale del campo.

Agradezco cualquier ayuda, sugerencia y/o comentaro. Gracias

Tengo un codigo resumen del programa mas grande pero no encuentro la manera de incluirlo. Si lo pego aqui me arroja un problema del servidor y si trato de adjuntarlo hace igual. Que puedo hacer para mostrarles el codigo???
Responder
#2
Hola, bienvenido.

Podés pegar directamente el código dentro de las etiquetas:

[ code]
aquí va el código
[ /code]

Sin los espacios dentro de los corchetes. Se va a ver así:

Código:
aquí va el código

Saludos
Responder
#3
Hola. Buenos dias.
He seguido tus instrucciones (eso creo). 
Entre las dos etquetas [ codigo] aqui va el codigo [ codigo ] puse todo el codigo (resumido) pero este es el mensaje que recibo al envar la respuesta

Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at webmaster@foro.recursospython.com to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.



sera acaso porque el codigo tiene  400 lineas??? (muy grande para enviar por aqui). El original tiene casi 1000 (957).

Ah perdoname. Muchas Gracias por responderme.

Tambien trate de enviarlo como un archivo anexo (adjunto) en forma normal y comprimido (.rar). De ninguna forma me permite. Te lo podriia enviar a una direccion de correo electronico (email)????
Responder
#4
Hola, Francisco.

Voy a consultar los registros de errores. 400 líneas no me parece mucho como para que arroje un error. Mientras, enviame el código por email a la casilla que te indico por mensaje privado.

Saludos
Responder
#5
Bien, recibí el código que me enviaste, y creo que para nuestro propósito se puede simplificar de la siguiente manera:

Código:
import tkinter as tk
from tkinter import messagebox, ttk


def msgerror(msg):
    messagebox.showerror ('ERROR:',msg)


def validarNroCedula(accion):
    global nrocedula, e11
    aux = nrocedula.get().strip()
    if aux == '':
        msgerror ('Nro. de Cedula no puede faltar.')
        nrocedula.set('')
        return False
    if not aux.isnumeric():
        msgerror ('Nro. de Cedula debe ser numerico')
        nrocedula.set('')
        return False
    aux = aux.rjust(10,'0')
    nrocedula.set(aux)
    return True


def validarapellidos(accion):
    global apellidos, e12
    aux = apellidos.get().strip().upper()
    if aux == '':
        msgerror ('El Apellido no puede faltar.')
        apellidos.set('')
        return False
    if not aux.isalpha():
        msgerror ('El Apellido debe ser alfabetico.')
        apellidos.set('')
        return False
    apellidos.set(aux)
    return True


ventana = tk.Tk()
ventana.title ("ACTUALIZAR EMPLEADO")
ventana.configure (width=820,height=450, bg='DarkSalmon')
nrocedula = tk.StringVar()
apellidos = tk.StringVar()
marco1 = tk.LabelFrame (ventana, text=" Datos-Personales ", width=800, height=80, bg='cyan')
marco1.place (x=10,y=30)
ttk.Label(marco1, text="Nro.Cedula").place(x=40,y=10)
ttk.Label(marco1, text="Apellidos").place(x=150,y=10)
e11 = ttk.Entry (marco1, textvariable=nrocedula, width=10, validate='focusout',
                validatecommand=(marco1.register(validarNroCedula),'%V'))
e11.place (x=40,y=30)
e12 = ttk.Entry (marco1, textvariable=apellidos, width=25, validate='focusout',
                validatecommand=(marco1.register(validarapellidos),'%V'))
e12.place (x=150,y=30)
ventana.mainloop()

Está bien que pongas la validación en "focusout", para que se ejecute cuando la caja de texto pierde el foco. Lo que veo es que al pasar el foco de la caja de la cédula a la caja del apellido (usando la tecla Tab o con el mouse) se ejecuta la validación de la cédula (lo cual es correcto, porque acaba de perder el foco), pero también se ejecuta la validación del apellido, y he aquí el problema porque el usuario todavía no tuvo tiempo de ingresar el apellido. No obstante, primero aparece el cuadro de diálogo relativo al error del apellido y luego aparece el relativo al error de la cédula. La causa de esto es que el mensaje mostrado por la función validarNroCedula() hace que la caja apellido pierda el foco (porque el mensaje es una nueva ventana que recibe el foco) y, por ende, antes de llegar a mostrar el mensaje, se ejecuta la función validarapellidos():

  1. def validarNroCedula(accion):
  2.     print("validarcedula")
  3.     global nrocedula, e11
  4.     aux = nrocedula.get().strip()
  5.     if aux == '':
  6.         # Este cuadro de diálogo hará que se pierda el foco
  7.         # de la caja de apellido y por ende se ejecute
  8.         # la función validarapellidos().
  9.         msgerror ('Nro. de Cedula no puede faltar.')
  10.         nrocedula.set('')
  11.         return False


Las aplicaciones de escritorio son un torrente continuo de eventos. El evento de pérdida de foco de la caja es anterior al evento de creación del mensaje o cuadro de diálogo, por eso aparece primero el mensaje de validación del apellido (aunque la validación de la cédula haya comenzado antes).

Se podría pensar una lógica con algunos booleanos para conseguir el comportamiento deseado, pero creo que sería más fácil y amigable para el usuario que simplemente muestres los mensajes de error en etiquetas (en lugar de usar cuadros de diálogo) debajo de cada caja de texto, como suele ocurrir en las aplicaciones web:

   

Saludos
Responder
#6
Hola
Buenos días.

Debo decir que estoy sorprendido por la enorme simplicidad a la cual tu redujiste mi código. Simplemente increíble pero cierto.
También me sorprende lo rápido que hiciste el análisis del problema y me planteas la solución. Gracias.
Esto solo lo puedo explicar a que posees una enorme experiencia y conocimiento del lenguaje.

Ahora que tengo la explicación de la causa del problema, voy a dedicarme a realizar los cambios respectivos para prescindir de los cuadros de dialogo atendiendo tu sugerencia.

Una de las varias cosas que intente antes de decidirme a solicitar tu ayuda, fue tratar de controlar los mensajes con suiches (booleanos). Si bien conseguí lograr que presentara el mensaje adecuado en el momento adecuado para algunas situaciones, no conseguí controlarlas todas y lo que arreglaba por un lado se me descontrolaba por otro. Nunca pude conseguir un control total y nunca se me ocurrió implementar tu sugerencia. Me gustaban (ya no) los cuadros de dialogo. También probé haciendo mi propia ventana de mensajes de error (ventana Toplevel), pero era igual.

Francisco, de tocayo a tocayo, muchas gracias.

Un saludo
Francisco Iglesias
Responder
#7
¡Un placer! Wink
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)