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