¿Cómo creo y uso atajos de teclado en una aplicación Gtk que estoy desarrollando?


9

Estoy creando una aplicación para Ubuntu App Showdown en Python + Gtk con rapidez. Lo llamo Discvur. Me hubiera gustado incluir algunos atajos de teclado.

Al buscar en la web, encontré esta página sobre AccelGroup y esta página sobre gtk_widget_add_accelerator, pero no entiendo cómo comenzar con ella. ¿Podría decirme cómo definiría una señal apropiada y luego la usaría en mi aplicación?


El primer enlace está roto ...
WinEunuuchs2Unix

Respuestas:


8

Aquí hay algunos bits de código de una de mis aplicaciones Python + Gtk, más ampliadas de acuerdo con los comentarios a esta respuesta:

self.my_accelerators = Gtk.AccelGroup()
self.entry = Gtk.builder.get_object("entry1")
self.add_accelerator(self.entry, "<Control>b", signal="backspace")
...

def add_accelerator(self, widget, accelerator, signal="activate"):
    """Adds a keyboard shortcut"""
    if accelerator is not None:
        #if DEBUG:
            #print accelerator, widget.get_tooltip_text()
        key, mod = Gtk.accelerator_parse(accelerator)
        widget.add_accelerator(signal, self.my_accelerators, key, mod, Gtk.AccelFlags.VISIBLE)

Gracias, pero me dio este mensaje: self.add_accelerator(self.quick_add_entry, "<Control>l", signal="grab-focus") AttributeError: 'DiscvurWindow' object has no attribute 'quick_add_entry'. Cuando intento una búsqueda web de "quick_add_entry", no puedo encontrarla en ningún lado. ¿Estás seguro de que es la función correcta? ¿Dónde puedo encontrar más información / un tutorial para esto? Además, ¿"<Control> l" significa Ctrl + l o es un tipo incorrecto?
Agmenor

No es una función, ese es solo el nombre de cualquier widget al que estés conectando el acelerador. Lo he revisado para que sea más claro.
Bryce

Gracias por su respuesta. Primero, me tomé la libertad de cambiar el "gtk" a "Gtk". En segundo lugar, cuando ejecuto su código obtengo "NameError: el nombre global 'DEBUG' no está definido", así que supongo que esta es una variable de su propio script. Así que lo comenté en mi propio guión. Tercero, después de haberlo comentado, aparece el error "AttributeError: el objeto 'DiscvurWindow' no tiene el atributo 'aceleradores'". Lamento si se supone que esto es evidente, pero la documentación todavía es oscura para mí; en particular la documentación dice que add_accelerator necesita 6 argumentos?
Agmenor

Bien, necesitas crear aceleradores tú mismo; He actualizado el ejemplo para mostrar cómo.
Bryce

Después de un poco de investigación e intentos fallidos, pude obtener un guión de trabajo. ¿Podrías verificarlo? Si crees que es correcto, modificaré (o puedes) tu respuesta: paste.ubuntu.com/1053516 . Le agradecería mucho su comentario, Bryce. "Un poco de investigación" era un eufemismo, pero supongo que es mejor aprender a pescar a un hombre que darle pescado. Así que gracias de nuevo.
Agmenor

6

Aquí está el código que finalmente funcionó. Como depende en gran medida de mi entorno de desarrollo Quickly + Glade + Python + Gtk, lo hago una respuesta independiente. La respuesta de Bryce ayudó mucho, y mis intercambios con aking1012 también .

El código real, en un editor de texto:

# Accelerators
self.my_accelerators = Gtk.AccelGroup()
self.window = self.builder.get_object("discvur_window")
self.window.add_accel_group(self.my_accelerators)
self.entry = self.builder.get_object("entry1")
self.add_accelerator(self.entry, "<Control>b", signal="backspace")



def add_accelerator(self, widget, accelerator, signal="activate"):
    """Adds a keyboard shortcut"""
    if accelerator is not None:
        #if DEBUG:
            #print accelerator, widget.get_tooltip_text()
        key, mod = Gtk.accelerator_parse(accelerator)
        widget.add_accelerator(signal, self.my_accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
        print "The accelerator is well added with the signal " + signal

def on_erasing(self, widget):
    print "It works."

En Glade, creé un GtkEntry llamado "entry1" en mi ventana llamada "discvur_window". En la pestaña 'Señales', le di a la señal "retroceso" un controlador llamado "on_erasing".

Ahora, presionar Backspaceo Ctrl+ Bhace que el terminal imprima "Funciona".


¿Se puede usar para deshabilitar el atajo Ctrl + F4 para cerrar la ventana?
Juzer Ali

¿Te refieres a Alt + F4? No sé, no lo he intentado.
Agmenor

Me refería a Ctrl + F4 y Alt + F4
Juzer Ali el

2

He reempacado las respuestas dadas en este hilo en un ejemplo independiente:

#!/usr/bin/env python2

import signal

from gi.repository import Gtk

def bind_accelerator(accelerators, widget, accelerator, signal='clicked'):
    key, mod = Gtk.accelerator_parse(accelerator)
    widget.add_accelerator(signal, accelerators, key, mod, Gtk.AccelFlags.VISIBLE)

def on_recompute_base_encryption_key_hash(widget):
    print 'Thinking... (This could take forever)'

def main():

    if 'gtk':
        window = Gtk.Window()
        window.connect("delete-event", Gtk.main_quit)

        if 'accelerator-demo':
            # Accelerators
            accelerators = Gtk.AccelGroup()
            window.add_accel_group(accelerators)

            # Widget
            target_widget = Gtk.Button('Recompute Base Encryption Key Hash')
            target_widget.connect('clicked', on_recompute_base_encryption_key_hash)
            window.add(target_widget)

            # Bind
            bind_accelerator(accelerators, target_widget, '<Control>b')

        window.show_all()
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        Gtk.main()

if __name__ == '__main__':
    main()

También disponible como una esencia: https://gist.github.com/thorsummoner/230bed5bbd3380bd5949

Nota: La señal predeterminada es clicked, no activateporque las aplicaciones nunca deberían conectarse a la ::activateseñal, sino porque usan la ::clickedseñal Gtk.Button .


Entonces me di cuenta; cuando se usa clickedel acelerador se puede machacar muy rápidamente, pero el botón no se presiona visualmente. Cuando se usa activate, el botón se presionará, pero el acelerador solo se puede presionar una vez que finaliza la depresión visual.
ThorSummoner
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.