热键及快捷键(GtkAccelGroup)


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

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
 posted on 2009-06-29 15:51  清水湾  阅读(759)  评论(0编辑  收藏  举报