Python 和 GTK+3:用于选择键盘快捷键的小部件
Python and GTK+3: widget for choosing a keyboard shortcut
我正在寻找一种在使用 Python 和 GTK+3 的对话框中添加快捷方式选择器小部件的方法。
我尝试搜索所有可用的小部件,但似乎没有找到任何开箱即用的解决方案。在这方面我最好的选择是什么?我应该使用 GtkEntry
并拦截按键吗?
虽然这看起来是一个很常见的用例,但我没能找到任何有效的例子。
没有开箱即用的解决方案,但您可能可以在 Keyboard panel of GNOME Control Center.
中找到适合的示例
我自己使用单独的对话框实现了这一点。有一个显示当前分配的常规按钮,单击该按钮会打开一个 KeyboardShortcutDialog
,实现如下:
class KeyboardShortcutDialog(Gtk.Dialog):
"""Dialog that allows to grab a keyboard shortcut."""
def __init__(self, parent):
Gtk.Dialog.__init__(self, _("Keyboard shortcut"), parent, 0)
self.shortcut = None
self.set_border_width(32)
# Add a label
label = Gtk.Label(xalign=0.5, yalign=0.5)
label.set_markup(
_('Press the desired key combination, <b>Backspace</b> to remove any shortcut, or <b>Esc</b> to cancel.'))
self.get_content_area().pack_start(label, True, True, 0)
self.connect('key-press-event', self.on_key_press)
self.show_all()
def on_key_press(self, widget, event: Gdk.EventKey):
"""Signal handler: key pressed."""
keyval = event.get_keyval()[1]
name = Gdk.keyval_name(keyval)
# For some reason event.is_modifier == 0 here, even for modifier keys, so we need to resort to checking by name
if name not in [
'Shift_L', 'Shift_R', 'Control_L', 'Control_R', 'Meta_L', 'Meta_R', 'Alt_L', 'Alt_R', 'Super_L',
'Super_R', 'Hyper_L', 'Hyper_R']:
logging.debug('Key pressed: state=%s, keyval=%d', event.state, keyval)
self.shortcut = (
keyval,
event.state &
(Gdk.ModifierType.META_MASK | Gdk.ModifierType.SUPER_MASK | Gdk.ModifierType.HYPER_MASK |
Gdk.ModifierType.SHIFT_MASK | Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK))
self.response(Gtk.ResponseType.ACCEPT)
return True
def run(self):
"""Show the dialog and block until it's closed.
:return: tuple (keyval, state) of the key captured or None if the dialog has been closed."""
super().run()
return self.shortcut
对话框的 run()
方法 returns 指定按下的组合键的元组。
我正在寻找一种在使用 Python 和 GTK+3 的对话框中添加快捷方式选择器小部件的方法。
我尝试搜索所有可用的小部件,但似乎没有找到任何开箱即用的解决方案。在这方面我最好的选择是什么?我应该使用 GtkEntry
并拦截按键吗?
虽然这看起来是一个很常见的用例,但我没能找到任何有效的例子。
没有开箱即用的解决方案,但您可能可以在 Keyboard panel of GNOME Control Center.
中找到适合的示例我自己使用单独的对话框实现了这一点。有一个显示当前分配的常规按钮,单击该按钮会打开一个 KeyboardShortcutDialog
,实现如下:
class KeyboardShortcutDialog(Gtk.Dialog):
"""Dialog that allows to grab a keyboard shortcut."""
def __init__(self, parent):
Gtk.Dialog.__init__(self, _("Keyboard shortcut"), parent, 0)
self.shortcut = None
self.set_border_width(32)
# Add a label
label = Gtk.Label(xalign=0.5, yalign=0.5)
label.set_markup(
_('Press the desired key combination, <b>Backspace</b> to remove any shortcut, or <b>Esc</b> to cancel.'))
self.get_content_area().pack_start(label, True, True, 0)
self.connect('key-press-event', self.on_key_press)
self.show_all()
def on_key_press(self, widget, event: Gdk.EventKey):
"""Signal handler: key pressed."""
keyval = event.get_keyval()[1]
name = Gdk.keyval_name(keyval)
# For some reason event.is_modifier == 0 here, even for modifier keys, so we need to resort to checking by name
if name not in [
'Shift_L', 'Shift_R', 'Control_L', 'Control_R', 'Meta_L', 'Meta_R', 'Alt_L', 'Alt_R', 'Super_L',
'Super_R', 'Hyper_L', 'Hyper_R']:
logging.debug('Key pressed: state=%s, keyval=%d', event.state, keyval)
self.shortcut = (
keyval,
event.state &
(Gdk.ModifierType.META_MASK | Gdk.ModifierType.SUPER_MASK | Gdk.ModifierType.HYPER_MASK |
Gdk.ModifierType.SHIFT_MASK | Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK))
self.response(Gtk.ResponseType.ACCEPT)
return True
def run(self):
"""Show the dialog and block until it's closed.
:return: tuple (keyval, state) of the key captured or None if the dialog has been closed."""
super().run()
return self.shortcut
对话框的 run()
方法 returns 指定按下的组合键的元组。