Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Capturar un evento antes que ocurra, tkinter.-
#1
Hola gente, ¿cómo están? Hola Francisco.
Créanme que como siempre antes de pedir ayuda busco práctico
y como en este caso cuando tengo que tirar la toalla recurro a Uds.
La consulta concreta es ¿hay alguna manera de capturar el evento
antes que se efectivice?, o ¿tiene esto otra solución?.-
En apariencia funciona, lo que ocurre es que cuando se ejecuta
la excepción el IDE se queda como en un bucle infinito y no se deja
cerrar.

Código:
#-------------------------------------------------------------------------------
# Name:        módulo1
# Purpose:     Copiar/pegar
#
# Author:      Daniel
#
# Created:     11/08/2022
# Copyright:   (c) Daniel 2022
# Licence:     <your licence>
#-------------------------------------------------------------------------------
import tkinter as tk
from tkinter import ttk
from functools import partial
import funciones

def rehacer(text, temp, event):
    try:
        text.edit_undo()
    except:
        text.insert(tk.INSERT, temp)

    return


def main():

    root = tk.Tk()

    text = tk.Text(root,width = 55,height = 10, undo=True)
    text.pack()

    temp = """ La inteligencia no se mide por el número
de palabras que sabes pronunciar,
sino por aquellas que no dices para no lastimar!!!
"""

    text.insert(tk.INSERT, temp)

    root.bind('<Control-z>', partial(rehacer, text, temp))
   
    root.mainloop()


if __name__ == '__main__':
    main()



Bueno, es todo, desde ya gracias, muchas gracias por el tiempo.

Slds. Daniel ☕☕☕
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#2
Hola, Daniel, ¿cómo estás?

No veo necesario que asocies el evento Ctrl + Z manualmente, eso ya lo hace por defecto el tk.Text (lo mismo que Ctrl + Y para rehacer). Cada vez que el usuario presiona Ctrl + Z, se genera un evento llamado <<Undo>>. Podés asociarle una función y retornar la cadena "break" cuando quieras abortar la propagación del evento.

Código:
import tkinter as tk


def undo(event):
    print("Deshacer cancelado.")
    # Cancelar el evento (tal vez con un condicional).
    return "break"


def main():
    root = tk.Tk()
    text = tk.Text(root, width=55, height=10, undo=True)
    text.pack()
    temp = """ La inteligencia no se mide por el número
de palabras que sabes pronunciar,
sino por aquellas que no dices para no lastimar!!!
"""
    text.insert(tk.INSERT, temp)
    text.bind("<<Undo>>", undo)
    root.mainloop()


if __name__ == '__main__':
    main()

Saludos
Responder
#3
Hola Francisco, que tengas un buen día, hola a todos.-
Bien, muy bueno, lo tuyo y en cuanto a la función "rehacer"
sabía que no tenía sentido, pero la puse con el afán de darme
a entender, desconocía tu función.-
Bueno y ahora, ¿cómo le doy sentido a ese condicional?, se
me antoja que si tendría acceso a la pila(que me imagino es
una lista) tendría forma de evitar que el TEXT me quede vacío,
¿eso no es factible no?.-

te dejo un ej. de lo que me pasa:

agrego 123
          456
          789

Si pulso <Control-z> 1 vez queda:
            123
            456

Si pulso <Control-z> otra vez queda:
            123
                     
Pulso <Control-z> otra vez deja el TEXT vacío, esto es lo que
deseo evitar... 


Slds. Daniel ☕☕☕
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#4
Hola, Daniel.

No andás con cosas fáciles vos... Big Grin

A la pila de operaciones que utiliza internamente el mecanismo de hacer/rehacer no es posible acceder. En realidad es una estructura implementada en C que almacena comandos de Tcl (insert, delete, etc.). Incluso si tuviéramos acceso, sería muy difícil determinar si el comando que está por ejecutarse va a dejar nuestra caja de texto vacía o no. Por ende lo único que se me ocurre es chequear si la caja de texto ha quedado vacía inmediatamente despúes de cada evento de deshacer, y en tal caso ejecutar edit_redo() para rehacer los cambios. No sé si es la solución más óptima, pero ahora creo que no se puede hacer otra cosa:

Código:
import tkinter as tk


def undo_before(event):
    event.widget.after(1, undo_after, event)


def undo_after(event):
    # Si el texto queda vacío, rehacer la última operación.
    if not event.widget.get("1.0", tk.END).strip():
        event.widget.edit_redo()


def main():
    root = tk.Tk()
    text = tk.Text(root, width=55, height=10, undo=True)
    text.pack()
    text.bind("<<Undo>>", undo_before)
    root.mainloop()


if __name__ == "__main__":
    main()

¡Saludos!
Responder
#5
Hola Francisco, ¿habré intentado pasarme de la raya? jajajajajaja
Gracias por tu tiempo y el código.-

Slds. Daniel ☕☕☕
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#6
Hola, ¿ cómo están?, buen día para todos.
Aquí les traigo algo interesante que soluciona todo con una línea.-

Código:
text.insert(tk.INSERT, temp)
text.edit_reset()

Les doy mi parecer, no lo den por sentado porque no lo encontré
escrito en ningún lado, tan solo se me ocurrió.-

Si hay algo escrito en el text al iniciar la pila lo copia y si luego
escribimos por ej.:

123
456

Al Deshacer primero borra 456 (último en entrar, primero en salir)
luego borra 123
y al final borrara lo primero que copio(el texto del widget text)
Si al iniciar ponemos la línea "text.edit_reset()" el text nunca quedará
vacío.-

Slds. Daniel ☕☕☕
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#7
¡Excelente, Daniel! Gracias por compartirlo.
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)