每个小部件加速器的Gtk

问题描述 投票:0回答:4

我构建了一个复合窗口小部件,希望它只有在焦点对准时才具有自己的加速器(热键)。到目前为止,我唯一想实现此目标的想法是,当我的窗口小部件进入和失去焦点时,请在顶层更改加速器组。似乎应该有更好的方法。

c gtk
4个回答
0
投票

每个小部件类都将指向其处理程序的指针作为小部件类的结构的一部分公开。您可以在调用gtk_init()之后但进入应用程序的主循环之前在运行时修补它们。

例如,您可以像这样修补GtkFoo的按键处理程序:

static gboolean (*oldFooKeyPress)(GtkWidget* _widget, GdkEventKey* _event);
...
GtkWidgetClass* fooClass = GTK_WIDGET_CLASS(g_type_class_ref(GTK_TYPE_FOO));
oldFooKeyPress = fooClass->key_press_event;
fooClass->key_press_event = myFooKeyPress;

然后您可以这样写myFooKeyPress()

static gboolean myFooKeyPress(GtkWidget* widget, GdkEventKey* event)
{
    if (widget is one I am interested in &&
        event is a special accelerator for that widget)
    {
        do something special here
        and maybe return
    }

    return oldFooKeyPress(widget, event);
}

我记得,当您进行上述修补时,如果尚未初始化Foo小部件类,则调用GTK_TYPE_FOO将对其进行初始化。


0
投票

0
投票

这里是类初始化函数,这是我一直在寻找的解决方案

static void
webview_class_init (WebviewClass *klass)
{

    GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);

    GtkBindingSet *binding_set;

    signals[ZOOM_IN] = g_signal_new_class_handler("zoom_in",
                    G_OBJECT_CLASS_TYPE (object_class),
                    G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                    G_CALLBACK (webview_zoom_in),
                    NULL, NULL,
                    g_cclosure_marshal_VOID__VOID,
                    G_TYPE_NONE, 1,
                    G_TYPE_BOOLEAN, TRUE);

    binding_set = gtk_binding_set_by_class (klass);

    gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK,
                    "zoom_in", 1,
                    G_TYPE_BOOLEAN, TRUE);

 }

0
投票

仅针对有针对性的小部件实现加速器,请参见this

步骤:

  • 创建新的GSimpleActionGroup,然后将其gtk_widget_insert_action_group到您的特定小部件。
  • 将动作添加到新的动作组中
  • 使用gtk_application_set_accels_for_action()设置该特定操作(名称)的快捷方式。
© www.soinside.com 2019 - 2024. All rights reserved.