GTK 菜单 快捷键

热键及快捷键(GtkAccelGroup)

热键:一般是字母带下划线.在当前控件内(如打开的菜单)可以用alt+字母来代替点击的功能
快捷键:一般指,在本窗口任何位置内,按某组合键,都可以代替点击的功能。
如果你的理解与我的有冲突,请以我的理解为准!
试举例证:
#include <gtk/gtk.h>
const char *txtShow = "http://tresss.com";

GtkWidget *frmMain, *tblTop, *txtTest, *lblShow,*btnSet,*btnGet;
GtkAccelGroup *agMain;

void destroy (GtkWidget *widget, gpointer *data)
{
    gtk_main_quit ();
}
//set Caption
void txt_setCaption (GtkWidget *widget, gpointer *data)
{
   gtk_entry_set_text(GTK_ENTRY(txtTest), txtShow);
}
//get Caption
void txt_getCaption (GtkWidget *widget, gpointer *data)
{
   gtk_label_set_text(GTK_LABEL(lblShow), gtk_entry_get_text(GTK_ENTRY(txtTest)));
}

int main(int argc, char *argv[])
{

  gtk_init (&argc, &argv);

  frmMain = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  gtk_signal_connect (GTK_OBJECT (frmMain), "destroy",GTK_SIGNAL_FUNC (destroy), NULL);
  gtk_container_border_width (GTK_CONTAINER (frmMain), 10);
  gtk_widget_add_events(frmMain, GDK_BUTTON_PRESS_MASK);

  tblTop = gtk_table_new(5,2,TRUE);
  gtk_container_add(GTK_CONTAINER(frmMain),tblTop);
 
  //controls create
  txtTest = gtk_entry_new();
  gtk_table_attach_defaults(GTK_TABLE(tblTop),txtTest,0,2,0,1);
  lblShow = gtk_label_new("Entry Info");
  gtk_table_attach_defaults(GTK_TABLE(tblTop),lblShow,0,2,1,2);
  btnSet = gtk_button_new_with_mnemonic("Set _Caption");
  gtk_table_attach_defaults(GTK_TABLE(tblTop),btnSet,0,1,2,3);
  btnGet = gtk_button_new_with_mnemonic("_Get Caption");
  gtk_table_attach_defaults(GTK_TABLE(tblTop),btnGet,1,2,2,3);
 
 
  //signal
  gtk_signal_connect(GTK_OBJECT(btnSet), "clicked", GTK_SIGNAL_FUNC(txt_setCaption), NULL);
  gtk_signal_connect(GTK_OBJECT(btnGet), "clicked", GTK_SIGNAL_FUNC(txt_getCaption), NULL);
  //bind Accelerate
  agMain = gtk_accel_group_new();
  gtk_window_add_accel_group(GTK_WINDOW(frmMain), agMain);
  gtk_widget_add_accelerator(btnGet, "clicked", agMain,GDK_g,GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);

  //Show everything;
  gtk_widget_show (frmMain);
  gtk_widget_show (tblTop);
  gtk_widget_show (txtTest);
  gtk_widget_show (lblShow);
  gtk_widget_show (btnSet);
  gtk_widget_show (btnGet);

  gtk_main ();

  return 0;
}


热键
可以看出.热键的使用很简单.
仅仅是用gtk_button_new_with_mnemonic代替了原来的创建函数gtk_button_new_with_label.
而且在想设为热键的字母前加一个下划线"_",这与其它语言也是有很大差异的.其它所有我了解的语言中,都是用"&"+字母来设定热键的,而这里 是"_"+字母.
当然,你有可能会在字符中使用"_"这个字符本身.这时,你可以用"__"连续的两个下划线来实现.在显示时,就会显示出字符"_".
编译后可以按"alt"+c,就会执行btnSet所连接的txt_setCaption()函数.

快捷键
GTK中的快捷键是通过GtkAccelGroup控件来实现的.
gtk_accel_group_new();创建函数没有任何参数.
gtk_window_add_accel_group(GTK_WINDOW(frmMain), agMain);这里是将GtkAccelGroup添加到窗体frmMain中.即表示只要是在窗体frmMain中按键,都会判断触发agMain设 定的快捷键.
gtk_widget_add_accelerator(btnGet, "clicked", agMain,GDK_g,GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
这里是真正的注册一个快捷键.第一个参数表示快捷键触发后要执行的对象.
第二个参数表示按键后,要触发这个对象的某个信号,这里是点击.
第三个参数表示是哪一个键.它定义在gdk/gdkkeysyms.h文件中,需要手动包含此文件.
第四个表示控件键.这里是ctrl键.
第五个参数是快捷键标志.官方文档没有太多说明.这个参数表示的是会在GtkAccelLabel控件中显示按键名.

第一和第二个参数其实就是表示,当按键被按下后要触发哪个控件的哪个信号.
第三和第四个参数就是表示注册的是哪个快捷键.
普通键在gdk/gdkkeysyms.h中有定义,你可以自已查找.
而控制键是一个掩码结构.说明如下:
enum GdkModifierType

typedef enum
{
GDK_SHIFT_MASK = 1 << 0,
GDK_LOCK_MASK = 1 << 1,
GDK_CONTROL_MASK = 1 << 2,
GDK_MOD1_MASK = 1 << 3,
GDK_MOD2_MASK = 1 << 4,
GDK_MOD3_MASK = 1 << 5,
GDK_MOD4_MASK = 1 << 6,
GDK_MOD5_MASK = 1 << 7,
GDK_BUTTON1_MASK = 1 << 8,
GDK_BUTTON2_MASK = 1 << 9,
GDK_BUTTON3_MASK = 1 << 10,
GDK_BUTTON4_MASK = 1 << 11,
GDK_BUTTON5_MASK = 1 << 12,

/* The next few modifiers are used by XKB, so we skip to the end.
* Bits 15 - 25 are currently unused. Bit 29 is used internally.
*/

GDK_SUPER_MASK = 1 << 26,
GDK_HYPER_MASK = 1 << 27,
GDK_META_MASK = 1 << 28,

GDK_RELEASE_MASK = 1 << 30,

GDK_MODIFIER_MASK = 0x5c001fff
} GdkModifierType;

说明:
GDK_SHIFT_MASK
the Shift key.
GDK_LOCK_MASK
a Lock key (depending on the modifier mapping of the X server
this may either be CapsLock or ShiftLock).
GDK_CONTROL_MASK
the Control key.
GDK_MOD1_MASK
the fourth modifier key (it depends on the modifier mapping of the X server which key is
interpreted as this modifier, but normally it is the Alt key).
GDK_MOD2_MASK
the fifth modifier key (it depends on the modifier mapping of the X server which key is
interpreted as this modifier).
GDK_MOD3_MASK
the sixth modifier key (it depends on the modifier mapping of the X server which key is
interpreted as this modifier).
GDK_MOD4_MASK
the seventh modifier key (it depends on the modifier mapping of the X server which key
is interpreted as this modifier).
GDK_MOD5_MASK
the eighth modifier key (it depends on the modifier mapping of the X server which key
is interpreted as this modifier).
GDK_BUTTON1_MASK
the first mouse button.
GDK_BUTTON2_MASK
the second mouse button.
GDK_BUTTON3_MASK
the third mouse button.
GDK_BUTTON4_MASK
the fourth mouse button.
GDK_BUTTON5_MASK
the fifth mouse button.
GDK_SUPER_MASK
the Super modifier. Since 2.10
GDK_HYPER_MASK
the Hyper modifier. Since 2.10
GDK_META_MASK
the Meta modifier. Since 2.10
GDK_RELEASE_MASK
not used in GDK itself. GTK+ uses it to differentiate between (keyval, modifiers) pairs from
key press and release events.
GDK_MODIFIER_MASK
a mask covering all modifier types.

可以看到,连鼠标按键都包含其中,但"win"键是不在其中的.
说明:这里的GDK_MOD1_MASK就是表示"alt"键的.

但现在有一个问题.就是,如果我想设快捷键为"F1"呢?即没有控制键.
很抱歉,GTK本身不提供这个功能.因为它们缺少一个成员来表示空值(已提交到官方bug网站,建议其添加一个成员).
所以只能如此做gtk_widget_add_accelerator(btnGet, "clicked", agMain,GDK_F1,(GdkModifierType)0, GTK_ACCEL_VISIBLE);
用0来表示不需要控制键,只要按F1就会触发事件.
同样,如果要设定"ctrl + alt + F1"这样的组合键,就如此gtk_widget_add_accelerator(btnGet, "clicked", agMain,GDK_F1,(GdkModifierType)(GDK_SHIFT_MASK | GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE);
第五个参数表示的是在GtkAccelLabel控件中显示按键名.即在右侧显示"ctrl+F1"字样.
但这里我们测试的是按钮.按钮上没有GtkAccelLabel.如果是菜单的话,由于GtkMenuItem默认会使用GtkAccelLabel控件 来显示字符,所以菜单上会提示此字样.
如果你要在变通按钮上使用快捷键,就只能手动添加上去了.

总体来说GTK的快捷键设置比较麻烦.但相对Windows开发,比较独立.
2008.12.03

=================================================
发现有时好像不行!
=================================================
gtk_accel_group_connect 看了看gtk+-2.4.14的代码, 总算搞定了,原来对 window = gtk_window_new(GTK_WINDOW_TOPLEVEL)生成的window的许多事件都不能使用 gtk_widget_add_accelerator() ,就是说有些信号不支持;尝试如下:

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkAccelGroup *accel = gtk_accel_group_new();
GClosure*closure=g_cclosure_new(G_CALLBACK(callback_func),user_data , NULL);
gtk_accel_group_connect (accel, GDK_q , 0, GTK_ACCEL_VISIBLE, closure); gtk_window_add_accel_group(GTK_WINDOW(window),accel);

还有个问题,如何给 callback_func() 传递 user_data, 似乎直接传不行!

============================================
============================================
对 于不能传递 user_data原因是callback_func 的格式
它的原型必须为:
gboolean            accel_func           (GtkAccelGroup *accel_group,
GObject *acceleratable,
guint keyval,
GdkModifierType modifier,
gpointer data);

=================================
=================================
另外对于由gtk_action_create_menu_item创建的菜单项使用函数
gtk_widget_add_accelerator关联快捷键时,能够相应快捷键,但是菜单项
后面没有相应的快捷键标识;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值