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


9

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

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


Первая ссылка не работает ...
— 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делает терминал печать «Это работает.».


Можно ли это использовать, чтобы отключить сочетание клавиш 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 .


Итак, я заметил; При использовании clickedускорителя пюре может быть очень быстрым, но кнопка визуально не нажимается. При использовании activateкнопка будет нажиматься, но акселератор может быть нажат только после того, как визуальное нажатие закончено.
— ThorSummoner
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.