Клавиатурные ускорители Python GTK3

Я работаю над созданием приложения для Ubuntu с использованием Python3 и Gtk3.

Я пытаюсь добавить в программу ускорители клавиатуры, но, к сожалению, продолжаю сталкиваться с проблемами.

Это мой код атм:

#! /bin/python

from gi.repository import Gtk, Gdk

class DeSedit(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="DeSedit")

        self.set_default_size(550, 350)

        # FileChooserDialog - Open File
        dialog = Gtk.FileChooserDialog("Select file to be opened", self,
            Gtk.FileChooserAction.OPEN,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OK, Gtk.ResponseType.OK))
        # keyboard shortcuts
        accel = Gtk.AccelGroup()
        self.add_accel_group(accel)
        self.add_accelerator(dialog, "<Control>o", signal="open")

        def add_accelerator(self, widget, accelerator, signal="activate"):
            """ adds <Control>o as accelerator for open-file dialog """
            if accelerator is not None:
                key, mod = Gtk.accelerator_parse(accelerator)
            widget.add_accelelator(signal, accel, key, mod, Gtk.AccelFlags.VISIBLE)
            print("works")

        # grid to organize widgets
        self.box = Gtk.Box()
        self.add(self.box)
        # text view
        self.textview = Gtk.TextView()
        self.textview.set_wrap_mode(True)
        # scroll bar
        scrollwindow = Gtk.ScrolledWindow()
        scrollwindow.add(self.textview)

        self.box.pack_start(scrollwindow, True, True, 0)


window = DeSedit()  # create DeSedit object
window.connect("delete-event", Gtk.main_quit)
window.show_all()
Gtk.main()

Я получаю эту ошибку:

Файл "file.py", строка 41, в 
    window = DeSedit()  # создать объект DeSedit
  Файл "file.py", строка 19, в __init__
    self.add_accelerator(self.dialog, "o", signal="open")
TypeError: add_accelerator() получил неожиданный аргумент ключевого слова 'signal'

1 ответ

Решение

Скорее всего, вы следуете руководству PyGtk 2, пытаясь реализовать это: Согласно документации GTK 3, нет функции с именем gtk_window_add_accelerator, но есть функция с именем gtk_accel_group_connect похоже, это будет сделано, чтобы сделать работу. При работе с документацией GTK это обычно 80% -ое чувство кишки и 20% -ная проверка документов, чтобы видеть, правильно ли вы. Не ожидайте каких-либо модных уроков или руководств (большую часть времени вы будете разочарованы)…

Во всяком случае: глядя на gtk_accel_group_connect В документации мы видим эти параметры: accel_group, accel_key, accel_mods, accel_flags а также closure,

Так как же вызвать эту функцию из Python? Давайте сделаем это шаг за шагом:

  1. Поскольку мы находимся в Python (объектно-ориентированный язык), мы можем ожидать accel_group параметр должен быть неявным, так как это первый параметр и ссылка на объект, который мы пытаемся изменить.
  2. Следующий параметр (accel_key) является более сложным: это целое число, и документация просто сообщает нам значение ключа ускорителя, что в основном означает , что вы сами должны выяснить, как найти значение ключа ускорителя. К счастью, быстрый поиск показывает функцию gdk_keyval_from_name который, кажется, делает то, что мы хотим. (И зовет Gdk.keyval_from_name('O') на самом деле возвращает правильный результат.)
  3. Следующий параметр accel_mods: Нажав на его тип (GdkModifierType) мы получаем хороший список всех возможных типов модификаторов. Как вы хотели использовать <Control> Модификатор мы можем просто использовать Gdk.ModifierType.CONTROL_MASK и двигаться дальше.
  4. accel_flags также имеет кликабельный тип (GtkAccelFlags) и открытие его описания показывает, что ни один из этих параметров не нужен, поэтому мы можем безопасно использовать 0 для этого параметра.
  5. Наконец-то мы на последнем параметре (closure): Поскольку closure это просто причудливое слово для обратного вызова (то, что должно вызываться, когда что-то происходит), мы можем просто использовать тот факт, что привязка Python GTK абстрагирует нас, и передать здесь вызываемую функцию, которая вызывается всякий раз, когда <Control>O был нажат.

В контексте код теперь выглядит так (проверено, что он работает):

#!/usr/bin/python3

from gi.repository import Gtk, Gdk

class DeSedit(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="DeSedit")

        self.set_default_size(550, 350)

        # FileChooserDialog - Open File
        dialog = Gtk.FileChooserDialog("Select file to be opened", self,
            Gtk.FileChooserAction.OPEN,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OK, Gtk.ResponseType.OK))
        # keyboard shortcuts
        accel = Gtk.AccelGroup()
        accel.connect(Gdk.keyval_from_name('O'), Gdk.ModifierType.CONTROL_MASK, 0, self.on_accel_pressed)
        self.add_accel_group(accel)

        # grid to organize widgets
        self.box = Gtk.Box()
        self.add(self.box)
        # text view
        self.textview = Gtk.TextView()
        self.textview.set_wrap_mode(True)
        # scroll bar
        scrollwindow = Gtk.ScrolledWindow()
        scrollwindow.add(self.textview)

        self.box.pack_start(scrollwindow, True, True, 0)

    def on_accel_pressed(self, *args):
        dialog = Gtk.FileChooserDialog("Select file to be opened", self,
            Gtk.FileChooserAction.OPEN,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OK, Gtk.ResponseType.OK))
        dialog.show()


window = DeSedit()  # create DeSedit object
window.connect("delete-event", Gtk.main_quit)

Надеюсь, это поможет вам начать с GTK+3!

Другие вопросы по тегам