Jak tworzyć i używać skrótów klawiaturowych w opracowywanej przeze mnie aplikacji Gtk?


9

Szybko tworzę aplikację dla Ubuntu App Showdown w Python + Gtk. Nazywam to Discvur. Chciałbym załączyć niektóre skróty klawiaturowe.

Przeszukując sieć, znalazłem tę stronę o AccelGroup i tę stronę o gtk_widget_add_accelerator, ale nie rozumiem, jak zacząć. Czy możesz mi powiedzieć, jak zdefiniowałbym odpowiedni sygnał, a następnie używał go w mojej aplikacji?


Pierwszy link jest zepsuty ...
— WinEunuuchs2Unix

Odpowiedzi:


8

Oto kilka fragmentów kodu z jednej z moich aplikacji Python + Gtk, dodatkowo rozszerzonych zgodnie z komentarzami do tej odpowiedzi:

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)

Dziękuję, ale mam ten błąd: self.add_accelerator(self.quick_add_entry, "<Control>l", signal="grab-focus") AttributeError: 'DiscvurWindow' object has no attribute 'quick_add_entry'. Gdy próbuję wyszukać w sieci hasło „szybkie_adres_wszelkie”, nie mogę go nigdzie znaleźć. Czy na pewno jest to właściwa funkcja? Gdzie mogę znaleźć więcej informacji / samouczek do tego? Ponadto, czy „<Control> l” oznacza Ctrl + l, czy jest to błąd?
— Agmenor,

To nie jest funkcja, to tylko nazwa widżetu, do którego podłączasz akcelerator. Poprawiłem to, aby było jaśniejsze.
— Bryce,

Dziękuję za Twoją odpowiedź. Po pierwsze, mogłem zmienić „GTK” na „Gtk”. Po drugie, kiedy uruchamiam kod, pojawia się komunikat „NameError: nazwa globalna„ DEBUG ”nie jest zdefiniowana”, więc przypuszczam, że jest to zmienna z twojego skryptu. Skomentowałem to więc we własnym skrypcie. Po trzecie, po skomentowaniu, pojawia się błąd „AttributeError: Obiekt„ DiscvurWindow ”nie ma atrybutu„ akceleratory ””. Przykro mi, jeśli ma to być oczywiste, ale dokumentacja wciąż jest dla mnie niejasna; w szczególności dokumentacja mówi, że add_accelerator potrzebuje 6 argumentów?
— Agmenor

Racja, musisz sam stworzyć akceleratory; Zaktualizowałem przykład, aby pokazać, jak to zrobić.
— Bryce

Po krótkich badaniach i nieudanych próbach mogłem uzyskać działający skrypt. Czy możesz to zweryfikować? Jeśli uważasz, że jest to poprawne, zmienię (lub możesz) twoją odpowiedź: paste.ubuntu.com/1053516 . Bardzo doceniam twoją recenzję, Bryce. „Małe badania” były eufemizmem, ale przypuszczam, że lepiej jest nauczyć człowieka, jak łowić, niż dawać mu ryby. Dziękuję jeszcze raz.
— Agmenor

6

Oto kod, który w końcu zadziałał. Ponieważ zależy to w dużej mierze od mojego środowiska programistycznego Quickly + Glade + Python + Gtk, robię z tego niezależną odpowiedź. Odpowiedź Bryce'a bardzo pomogła, podobnie jak moja wymiana z aking1012 .

Rzeczywisty kod w edytorze tekstu:

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

W Glade utworzyłem GtkEntry o nazwie „entry1” w moim oknie o nazwie „discvur_window”. W zakładce „Sygnały” nadałem sygnałowi „backspace” moduł obsługi o nazwie „on_erasing”.

Teraz, naciśnięcie Backspacelub Ctrl+ Bpowoduje, że terminal wypisuje „To działa”.


Czy można tego użyć, aby wyłączyć skrót Ctrl + F4, aby zamknąć okno?
— Juzer Ali

Masz na myśli Alt + F4? Nie wiem, nie próbowałem.
— Agmenor,

Miałem na myśli zarówno Ctrl + F4, jak i Alt + F4
— Juzer Ali

2

Przepakowałem podane odpowiedzi w tym wątku do samodzielnego przykładu:

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

Dostępne również jako gist: https://gist.github.com/thorsummoner/230bed5bbd3380bd5949

Uwaga: Domyślnym sygnałem jest clickednie activatedlatego , że aplikacje nigdy nie powinny łączyć się z ::activatesygnałem, ale używać ::clickedsygnału Gtk.Button .


Więc zauważyłem; podczas używania clickedakceleratora można bardzo szybko zmiażdżyć, ale przycisk nie naciska wizualnie. Podczas używania activateprzycisk zostanie wciśnięty, ale akcelerator można nacisnąć dopiero po zakończeniu wizualnego wciśnięcia.
— ThorSummoner,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.