更改由 glade 设置的 Gtk 加速器
Changing Gtk accelerator set by glade
我正在使用 Gtk (python3) + Glade 创建一个应用程序。我像这样在林间空地设置了一些加速器:
<child>
<object class="GtkImageMenuItem" id="imagemenuitem5">
<property name="label">gtk-quit</property>
<accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
</child>
但我不知道如何在应用程序处于 运行 时将此事件的加速器更改为其他东西。可能吗?我计划执行的操作是否错误?
<accelerator>
元素在内部使用 gtk_widget_add_accelerator()
。来自该函数的文档:
Accelerators added through this function are not user changeable during runtime. If you want to support accelerators that can be changed by the user, use gtk_accel_map_add_entry()
and gtk_widget_set_accel_path()
or gtk_menu_item_set_accel_path()
instead.
事实上,还有一种比这更现代的方法,使用 GAction
、GApplication
和 GMenuModel
,根本不创建任何菜单栏。下面是在运行时更改菜单项的快捷键的示例:
from gi.repository import Gio, Gtk
class App(Gtk.Application):
def __init__(self, **props):
super(App, self).__init__(application_id='org.gnome.example',
flags=Gio.ApplicationFlags.FLAGS_NONE, **props)
# Activating the LEP GEX VEN ZEA menu item will rotate through these
# accelerator keys
self.keys = ['L', 'G', 'V', 'Z']
def do_activate(self):
Gtk.Application.do_activate(self)
actions = self.create_actions()
self.add_action(actions['quit'])
self.win = Gtk.ApplicationWindow()
self.add_window(self.win)
self.win.add_action(actions['lep'])
self.set_accels_for_action('win.lep', ['<primary>' + self.keys[0]])
# Ctrl-Q is automatically assigned to an app action named quit
model = self.create_menus()
self.set_menubar(model)
actions['lep'].connect('activate', self.on_lep_activate)
actions['quit'].connect('activate', lambda *args: self.win.destroy())
self.win.show_all()
def create_actions(self):
return {name: Gio.SimpleAction(name=name) for name in ['lep', 'quit']}
def create_menus(self):
file_menu = Gio.Menu()
file_menu.append('LEP GEX VEN ZEA', 'win.lep')
file_menu.append('Quit', 'app.quit')
menu = Gio.Menu()
menu.append_submenu('File', file_menu)
return menu
def on_lep_activate(self, *args):
self.keys = self.keys[1:] + self.keys[:1]
self.set_accels_for_action('win.lep', ['<primary>' + self.keys[0]])
if __name__ == '__main__':
App().run([])
您也可以使用 Glade 文件执行其中一些操作,并通过创建一个 menus.ui
文件并使其在特定 GResource 路径上可供您的应用程序使用来自动连接它:这在 here 中有描述.
我正在使用 Gtk (python3) + Glade 创建一个应用程序。我像这样在林间空地设置了一些加速器:
<child>
<object class="GtkImageMenuItem" id="imagemenuitem5">
<property name="label">gtk-quit</property>
<accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
</child>
但我不知道如何在应用程序处于 运行 时将此事件的加速器更改为其他东西。可能吗?我计划执行的操作是否错误?
<accelerator>
元素在内部使用 gtk_widget_add_accelerator()
。来自该函数的文档:
Accelerators added through this function are not user changeable during runtime. If you want to support accelerators that can be changed by the user, use
gtk_accel_map_add_entry()
andgtk_widget_set_accel_path()
orgtk_menu_item_set_accel_path()
instead.
事实上,还有一种比这更现代的方法,使用 GAction
、GApplication
和 GMenuModel
,根本不创建任何菜单栏。下面是在运行时更改菜单项的快捷键的示例:
from gi.repository import Gio, Gtk
class App(Gtk.Application):
def __init__(self, **props):
super(App, self).__init__(application_id='org.gnome.example',
flags=Gio.ApplicationFlags.FLAGS_NONE, **props)
# Activating the LEP GEX VEN ZEA menu item will rotate through these
# accelerator keys
self.keys = ['L', 'G', 'V', 'Z']
def do_activate(self):
Gtk.Application.do_activate(self)
actions = self.create_actions()
self.add_action(actions['quit'])
self.win = Gtk.ApplicationWindow()
self.add_window(self.win)
self.win.add_action(actions['lep'])
self.set_accels_for_action('win.lep', ['<primary>' + self.keys[0]])
# Ctrl-Q is automatically assigned to an app action named quit
model = self.create_menus()
self.set_menubar(model)
actions['lep'].connect('activate', self.on_lep_activate)
actions['quit'].connect('activate', lambda *args: self.win.destroy())
self.win.show_all()
def create_actions(self):
return {name: Gio.SimpleAction(name=name) for name in ['lep', 'quit']}
def create_menus(self):
file_menu = Gio.Menu()
file_menu.append('LEP GEX VEN ZEA', 'win.lep')
file_menu.append('Quit', 'app.quit')
menu = Gio.Menu()
menu.append_submenu('File', file_menu)
return menu
def on_lep_activate(self, *args):
self.keys = self.keys[1:] + self.keys[:1]
self.set_accels_for_action('win.lep', ['<primary>' + self.keys[0]])
if __name__ == '__main__':
App().run([])
您也可以使用 Glade 文件执行其中一些操作,并通过创建一个 menus.ui
文件并使其在特定 GResource 路径上可供您的应用程序使用来自动连接它:这在 here 中有描述.