Comment créer et utiliser des raccourcis clavier dans une application Gtk que je développe?

9

Je crée une application pour le Showdown d'application Ubuntu en Python + Gtk avec rapidement. Je l'appelle Discvur. J'aurais aimé inclure quelques raccourcis clavier.

En recherchant sur le Web, j'ai trouvé cette page sur AccelGroup et cette page sur gtk_widget_add_accelerator mais je ne comprends pas comment commencer avec. Pourriez-vous me dire comment je définirais un signal approprié, puis l'utiliser dans mon application?

Agmenor
la source
Le premier lien est rompu ...
WinEunuuchs2Unix

Réponses:

8

Voici quelques morceaux de code de l'une de mes applications Python + Gtk, étendus en fonction des commentaires de cette réponse:

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)
Bryce
la source
Merci , mais je suis arrivé cette erreur: self.add_accelerator(self.quick_add_entry, "<Control>l", signal="grab-focus") AttributeError: 'DiscvurWindow' object has no attribute 'quick_add_entry'. Lorsque j'essaie une recherche sur le Web de "quick_add_entry", je ne le trouve nulle part. Êtes-vous sûr que c'est la bonne fonction? Où puis-je trouver plus d'informations / un tutoriel pour cela? De plus, "<Control> l" signifie-t-il Ctrl + l ou s'agit-il d'un type erroné?
Agmenor
Ce n'est pas une fonction, c'est juste le nom du widget auquel vous connectez l'accélérateur. Je l'ai révisé pour être plus clair.
Bryce
Merci pour votre réponse. Tout d'abord, j'ai pris la liberté de changer le "gtk" en "Gtk". Deuxièmement, lorsque j'exécute votre code, j'obtiens "NameError: le nom global 'DEBUG' n'est pas défini", donc je suppose que c'est une variable de votre propre script. Je l'ai donc commenté dans mon propre script. Troisièmement, après l'avoir commenté, j'obtiens l'erreur "AttributeError: l'objet 'DiscvurWindow' n'a pas d'attribut 'accélérateurs'". Je suis désolé si cela est censé être évident, mais la documentation est toujours obscure pour moi; en particulier, la documentation indique que add_accelerator a besoin de 6 arguments?
Agmenor
À droite, vous devez créer vous-même des accélérateurs; J'ai mis à jour l'exemple pour montrer comment.
Bryce
Après quelques recherches et essais infructueux, j'ai pu obtenir un script de travail. Pourriez-vous s'il vous plaît le vérifier? Si vous pensez que c'est correct, je vais (ou vous pouvez) modifier votre réponse: paste.ubuntu.com/1053516 . J'apprécierais beaucoup votre avis, Bryce. "Un peu de recherche" était un euphémisme, mais je suppose qu'il vaut mieux apprendre à un homme à pêcher que de lui donner du poisson. Merci encore.
Agmenor
6

Voici le code qui a finalement fonctionné. Comme cela dépend fortement de mon environnement de développement Quickly + Glade + Python + Gtk, j'en fais une réponse indépendante. La réponse de Bryce a beaucoup aidé, tout comme mes échanges avec aking1012 .

Le code réel, dans un éditeur de texte:

# 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."

Dans Glade, j'ai créé un GtkEntry appelé "entry1" dans ma fenêtre appelé "discvur_window". Dans l'onglet 'Signaux', j'ai donné au signal "backspace" un gestionnaire appelé "on_erasing".

Maintenant, en appuyant sur Backspaceou Ctrl+, Ble terminal affiche "Ça marche".

Agmenor
la source
Peut-il être utilisé pour désactiver le raccourci Ctrl + F4 pour fermer la fenêtre?
Juzer Ali
Vous voulez dire Alt + F4? Je ne sais pas, je n'ai pas essayé.
Agmenor
Je voulais dire à la fois Ctrl + F4 et Alt + F4
Juzer Ali
2

J'ai reconditionné les réponses données dans ce fil dans un exemple autonome:

#!/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()

Également disponible en tant qu'essentiel: https://gist.github.com/thorsummoner/230bed5bbd3380bd5949

Remarque: Le signal par défaut est clicked, non pas activateparce que les applications ne doivent jamais se connecter au ::activatesignal, mais utiliser le ::clickedsignal Gtk.Button .

ThorSummoner
la source
J'ai donc remarqué; lors de l'utilisation de clickedl'accélérateur peut être écrasé très rapidement, mais le bouton ne déprime pas visuellement. Lors de l'utilisation activate, le bouton s'enfonce, mais l'accélérateur ne peut être enfoncé qu'une fois la dépression visuelle terminée.
ThorSummoner