Wie erstelle und verwende ich Tastaturkürzel in einer von mir entwickelten Gtk-App?

9

Ich erstelle schnell eine Anwendung für den Ubuntu App Showdown in Python + Gtk. Ich nenne es Discvur. Ich hätte gerne einige Tastaturkürzel eingefügt.

Beim Durchsuchen des Webs habe ich diese Seite über AccelGroup und diese Seite über gtk_widget_add_accelerator gefunden, aber ich verstehe nicht, wie ich damit anfangen soll. Können Sie mir sagen, wie ich ein geeignetes Signal definieren und es dann in meiner Anwendung verwenden würde?

Agmenor
quelle
Der erste Link ist defekt ...
WinEunuuchs2Unix

Antworten:

8

Hier sind einige Code-Teile aus einer meiner Python + Gtk-Apps, die gemäß den Kommentaren zu dieser Antwort weiter erweitert wurden:

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
quelle
Danke, aber ich habe diesen Fehler bekommen : self.add_accelerator(self.quick_add_entry, "<Control>l", signal="grab-focus") AttributeError: 'DiscvurWindow' object has no attribute 'quick_add_entry'. Wenn ich eine Websuche nach "quick_add_entry" versuche, kann ich sie nirgendwo finden. Sind Sie sicher, dass es die richtige Funktion ist? Wo finde ich weitere Informationen / ein Tutorial dazu? Bedeutet "<Steuerung> l" außerdem Strg + l oder handelt es sich um einen Fehlertyp?
Agmenor
Es ist keine Funktion, sondern nur der Name des Widgets, mit dem Sie den Beschleuniger verbinden. Ich habe es überarbeitet, um es klarer zu machen.
Bryce
Vielen Dank für Ihre Antwort. Zuerst habe ich mir erlaubt, das "gtk" in "Gtk" zu ändern. Zweitens, wenn ich Ihren Code ausführe, erhalte ich "NameError: Der globale Name 'DEBUG' ist nicht definiert". Ich nehme an, dies ist eine Variable aus Ihrem eigenen Skript. Also habe ich es in meinem eigenen Skript kommentiert. Drittens erhalte ich nach dem Kommentieren die Fehlermeldung "AttributeError: 'DiscvurWindow'-Objekt hat kein Attribut' Beschleuniger '". Es tut mir leid, wenn dies offensichtlich sein soll, aber die Dokumentation ist für mich immer noch dunkel; Insbesondere heißt es in der Dokumentation, dass add_accelerator 6 Argumente benötigt.
Agmenor
Richtig, Sie müssen selbst Beschleuniger erstellen. Ich habe das Beispiel aktualisiert, um zu zeigen, wie.
Bryce
Nach ein wenig Recherche und fehlgeschlagenen Versuchen konnte ich ein funktionierendes Skript bekommen. Könnten Sie es bitte überprüfen? Wenn Sie denken, dass es richtig ist, werde ich (oder Sie können) Ihre Antwort ändern: paste.ubuntu.com/1053516 . Ich würde mich sehr über Ihre Bewertung freuen, Bryce. "Ein bisschen Forschung" war ein Euphemismus, aber ich nehme an, es ist besser, einem Mann das Fischen beizubringen, als ihm Fisch zu geben. Also nochmals vielen Dank.
Agmenor
6

Hier ist der Code, der endlich funktioniert hat. Da dies stark von meiner Entwicklungsumgebung abhängt, mache ich Quickly + Glade + Python + Gtk zu einer unabhängigen Antwort. Bryces Antwort hat mir sehr geholfen, ebenso wie mein Austausch mit aking1012 .

Der eigentliche Code in einem Texteditor:

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

In Glade habe ich in meinem Fenster einen "GtkEntry" namens "entry1" mit dem Namen "discvur_window" erstellt. Auf der Registerkarte "Signale" habe ich dem Signal "Rücktaste" einen Handler namens "on_erasing" gegeben.

Wenn Sie jetzt Backspaceoder Ctrl+ Bdrücken, wird auf dem Terminal "Es funktioniert" gedruckt.

Agmenor
quelle
Kann dies verwendet werden, um die Tastenkombination Strg + F4 zu deaktivieren und das Fenster zu schließen?
Juzer Ali
Du meinst Alt + F4? Ich weiß nicht, ich habe es nicht versucht.
Agmenor
Ich meinte sowohl Strg + F4 als auch Alt + F4
Juzer Ali
2

Ich habe die Antworten in diesem Thread in ein eigenständiges Beispiel umgepackt:

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

Auch als Kern verfügbar: https://gist.github.com/thorsummoner/230bed5bbd3380bd5949

Hinweis: Das Standardsignal ist clickednicht, activateweil Anwendungen niemals eine Verbindung zum ::activateSignal herstellen sollten, sondern das Gtk.Button- ::clickedSignal verwenden.

ThorSummoner
quelle
Also bemerkte ich; Bei Verwendung clickeddes Gaspedals kann sehr schnell püriert werden, aber die Taste drückt nicht visuell. Bei Verwendung activatewird die Taste gedrückt, aber das Gaspedal kann erst gedrückt werden, wenn das visuelle Drücken beendet ist.
ThorSummoner