Как создать и использовать сочетания клавиш в разрабатываемом приложении Gtk?

9

Я быстро создаю приложение для Ubuntu App Showdown в Python + Gtk. Я называю это Discvur. Я хотел бы включить некоторые сочетания клавиш.

Ища в Интернете, я нашел эту страницу о AccelGroup и эту страницу о gtk_widget_add_accelerator, но я не понимаю, как начать с него. Не могли бы вы сказать мне, как бы я определил соответствующий сигнал, а затем использовать его в моем приложении?

Agmenor
источник
Первая ссылка не работает ...
WinEunuuchs2Unix

Ответы:

8

Вот некоторые фрагменты кода из одного из моих приложений Python + Gtk, дополнительно дополненные комментариями к этому ответу:

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)
Брайс
источник
Спасибо , но я получил эту ошибку: self.add_accelerator(self.quick_add_entry, "<Control>l", signal="grab-focus") AttributeError: 'DiscvurWindow' object has no attribute 'quick_add_entry'. Когда я пытаюсь найти в сети «quick_add_entry», я нигде не могу его найти. Вы уверены, что это правильная функция? Где я могу найти больше информации / учебник для этого? Кроме того, <Control> l означает Ctrl + l или это ошибочный тип?
Агменор
Это не функция, это просто имя любого виджета, к которому вы подключаете ускоритель. Я пересмотрел это, чтобы быть более понятным.
Брайс
Спасибо за ваш ответ. Во-первых, я позволил себе сменить «gtk» на «gtk». Во-вторых, когда я запускаю ваш код, я получаю «NameError: глобальное имя« DEBUG »не определено», поэтому я предполагаю, что это переменная из вашего собственного скрипта. Поэтому я прокомментировал это в своем собственном сценарии. В-третьих, после его комментирования я получаю сообщение об ошибке «AttributeError: объект DiscvurWindow не имеет атрибута« ускорители »». Я извиняюсь, если это должно быть очевидно, но документация все еще неясна для меня; в частности, в документации сказано, что add_accelerator нужно 6 аргументов?
Агменор
Правильно, вам нужно создавать ускорители самостоятельно; Я обновил пример, чтобы показать, как.
Брайс
После небольшого исследования и неудачных попыток я смог получить рабочий сценарий. Не могли бы вы подтвердить это? Если вы считаете, что это правильно, я буду (или вы можете) изменить ваш ответ: paste.ubuntu.com/1053516 . Я был бы очень признателен за ваш отзыв, Брайс. «Небольшое исследование» было эвфемизмом, но я полагаю, лучше научить человека ловить рыбу, чем давать ему рыбу. Так что спасибо еще раз.
Агменор
6

Вот код, который наконец заработал. Поскольку это сильно зависит от моей среды разработки Quickly + Glade + Python + Gtk, я делаю это независимым ответом. Ответ Брайса очень помог, как и мои обмены с aking1012 .

Фактический код в текстовом редакторе:

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

В Glade я создал GtkEntry с именем "entry1" в моем окне с именем "discvur_window". На вкладке «Сигналы» я дал сигналу «backspace» обработчик под названием «on_erasing».

Теперь, попав Backspaceили Ctrl+ Bделает терминал печать «Это работает.».

Agmenor
источник
Можно ли это использовать, чтобы отключить сочетание клавиш Ctrl + F4, чтобы закрыть окно?
Джузер Али
Вы имеете в виду Alt + F4? Я не знаю, я не пробовал.
Агменор
Я имел в виду и Ctrl + F4 и Alt + F4
Джузер Али
2

Я переупаковал данные ответы в этой теме в отдельный пример:

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

Также доступный как суть: https://gist.github.com/thorsummoner/230bed5bbd3380bd5949

Примечание: сигнал по умолчанию - clickedне activateпотому , что приложения никогда не должны подключаться к ::activateсигналу, а использовать ::clickedсигнал Gtk.Button .

ThorSummoner
источник
Итак, я заметил; При использовании clickedускорителя пюре может быть очень быстрым, но кнопка визуально не нажимается. При использовании activateкнопка будет нажиматься, но акселератор может быть нажат только после того, как визуальное нажатие закончено.
ThorSummoner