第89页的gtk+编程例子——协调工具条和菜单项

以下gtk+编程例子是来自书籍《实用技术:开发Linux应用——用GTK+和GDK开发Linux图形用户界面应用》第89页的内容——协调工具条和菜单项

书中协调的意思是,在工具条选择了两种字体,那么在菜单是也同步显示已经勾选了两种字体,在工具条在不勾选三种字体,那么在菜单是也同步显示不勾选三种字体,书在的方案是写一个自定义程序将菜单的返回值(true或false)与工具条的返回值一致,它是使用复合框combo将三种字体组合在一起加入到工具条的,因为CreateCombobox()是在书中没有贴出源代码,本人也不知道如何实现,而参考gtk3.0的API手册,有两个函数GtkMenuToolButton和GtkRadioToolButton是能够实现协调功能的,也不用写自定义程序,经过测试GtkMenuToolButton已经成功实现,但测试GtkRadioToolButton不成功,太复杂,难以明白,暂时无解

在openSUSE-Leap-15.3-DVD-x86_64的gnome3.34.7桌面环境下编译的,其中pkg-config --cflags --libs gtk±3.0两边有反引号括起来的
ruhong@localhost:~/gtk> gcc page89.c -o page89 pkg-config --cflags --libs gtk±3.0
ruhong@localhost:~/gtk> ./page89

/* the example on page 89 */

#include <gtk/gtk.h>
/* 准备材料,自定义函数  */
	/*  comments注释  */

void shortcut_key_action (GtkWidget *widget, gpointer *data)
{
	g_print ("当你按下组合键 %s 时,在终端能看到此条信息表明组合键已经产生动作了\n", data);
}
	/*  正常情况下当你按下组合键会跳出一个对话框的,但是这只是一个小程序并没有完善,为了显示你按下组合键的结果,就简单地在终端能看到此条信息表明组合键已经产生动作了,这个动作与你使用鼠标点击命令是一样的 */


/* 程序主体 */
int main( int argc, char *argv[] )
{
	GtkWidget *window;
	/* 声明变量window为构件gtkwidget */
	GtkAccelGroup *accel_group;
	/* 声明变量accel_group为快捷键组GtkAccelGroup类型 */
	GtkWidget *vbox;
	GtkWidget *menubar;
	GtkWidget *toolbar;
	GtkWidget *file;
	GtkWidget *edit;
	GtkWidget *surface;
	GtkWidget *help;
	GtkWidget *filemenu;
	GtkWidget *new;
	GtkWidget *open;
	GtkWidget *save;
	GtkWidget *saveas;
	GtkWidget *separator_menu;
	GtkWidget *quit;
	GtkWidget *editmenu;
	GtkWidget *copy;
	GtkWidget *cut;
	GtkWidget *paste;
	GtkWidget *find;
	GtkWidget *replace;
	GtkWidget *surfacemenu;
	GtkWidget *font;
	GtkWidget *skin;
	GtkWidget *fontmenu;
	GtkWidget *font1;
	GtkWidget *font2;
	GtkWidget *font3;
	GtkWidget *skinmenu;
	GtkWidget *skin1;
	GtkWidget *skin2;
	GtkWidget *skin3;
	GSList *groupskin = NULL;
	/* 声明变量groupskin为GSList类型并设定初始值为NULL */
	GtkWidget *helpmenu;
	GtkWidget *helpf1;
	GtkWidget *aboutf7;
	GtkToolItem *newtool;
	/* 声明变量newtool为GtkToolItem类型 */
	GtkToolItem *opentool;
	GtkToolItem *savetool;
	GtkToolItem *saveastool;
	GtkToolItem *quittool;
	GtkToolItem *separator_tool;
	GtkToolItem *copytool;
	GtkToolItem *cuttool;
	GtkToolItem *pastetool;
	GtkToolItem *findtool;
	GtkToolItem *replacetool;
	GtkToolItem *fonttool;
	GtkToolItem *skintool;
	GtkToolItem *helpf1tool;
	GtkToolItem *aboutf7tool;
	GtkWidget *fontimage;

	gtk_init (&argc, &argv);
	/* 初始化gtk */

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	/*  创建顶级窗口 */
	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
	/*  设置窗口位置为显示器的中间 */
	gtk_window_set_default_size(GTK_WINDOW(window), 1000, 200);
	/*  设置窗口的大小,横为1000像素,竖为200像素 */
	gtk_window_set_title (GTK_WINDOW (window), "协调工具条和菜单项");
	/*  为窗口顶部加上标题为协调工具条和菜单项 */
	g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
	/*  为窗口加上动作,当收到destroy信号,就启动gtk_main_quit事件,gtk_main_quit就是鼠标单击窗口右上角的关闭按钮就终止程序  */
	gtk_container_set_border_width (GTK_CONTAINER (window), 0);
	/*  简单的理解是将窗口变成容器,可以装入其它构件,构件边缘与窗口边缘的距离为0像数  */
	accel_group = gtk_accel_group_new ();
	/*  创建快捷键组accel_group */
	gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
	/*  将快捷键组装入窗口容器 */
	
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	/*  创建组合框  */
	gtk_container_add (GTK_CONTAINER (window), vbox);
	/*  将组合框装入窗口容器  */

	menubar = gtk_menu_bar_new ();
	/*  创建菜单条  */
	gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, TRUE, 0);
	/*  将菜单条装入组合框容器  */
	
	toolbar = gtk_toolbar_new ();
	/*  创建工具条  */
	gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); 
	/*  设置工具条要只显示图标,不显示文字  */
	gtk_box_pack_start (GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
	/*  将工具条装入组合框容器  */
	
	file = gtk_menu_item_new_with_label ("文件");
	/*  创建名称文件  */
	gtk_menu_shell_append (GTK_MENU_SHELL(menubar), file);
	/*  将名称file加入菜单条menubar  */
	edit = gtk_menu_item_new_with_label ("编辑");
	gtk_menu_shell_append (GTK_MENU_SHELL(menubar), edit);
	surface = gtk_menu_item_new_with_label ("外观");
	gtk_menu_shell_append (GTK_MENU_SHELL(menubar), surface);
	help = gtk_menu_item_new_with_label ("帮助");
	gtk_menu_shell_append (GTK_MENU_SHELL(menubar), help);


	filemenu = gtk_menu_new ();
	/*  类似创建文件菜单组 */
	gtk_menu_item_set_submenu (GTK_MENU_ITEM (file), filemenu);
	new = gtk_menu_item_new_with_label ("新建");
	/*  创建名称新建new  */
	gtk_menu_shell_append (GTK_MENU_SHELL (filemenu), new);
	/*  将名称新建new加入文件菜单组filemenu  */
	g_signal_connect(G_OBJECT(new), "activate", G_CALLBACK(shortcut_key_action), "ctrl-n新建");
	/*  为new构件加上鼠标点击动作,当鼠标点击new构件时,就启动shortcut_key_action事件,shortcut_key_action就是在终端显示一条信息表明鼠标点击产生结果了  */
	gtk_widget_add_accelerator (new, "activate", accel_group, GDK_KEY_n, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	/*  为new构件加上快捷组合键动作,当在键盘上按下new构件的组合键ctrl-n新建时,就启动shortcut_key_action事件,shortcut_key_action就是在终端显示一条信息表明快捷组合键产生结果了  */
	newtool = gtk_tool_button_new (NULL, NULL);
	/*  创建工具条按钮newtool,不带有图片,不带有文字  */
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(newtool), "document-new");
	/*  从系统自带图标库中指定document-new图片作为工具条按钮的图片  */
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (newtool), "新建一个文件");
	/*  为工具条按钮加入文字提示,当鼠标停留在图标就会出现文字提示  */
	g_signal_connect(G_OBJECT(newtool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-n新建");
	/*  为工具条按钮newtool加上鼠标点击动作,当鼠标点击newtool构件时,就启动shortcut_key_action事件,shortcut_key_action就是在终端显示一条信息表明鼠标点击产生结果了  */
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), newtool, -1);
	/*  将新建工具条按钮加入到工具条中,-1表示从后面加入  */

	open = gtk_menu_item_new_with_label ("打开");
	gtk_menu_shell_append (GTK_MENU_SHELL (filemenu), open);
	g_signal_connect(G_OBJECT(open), "activate", G_CALLBACK(shortcut_key_action), "ctrl-o打开");
	gtk_widget_add_accelerator (open, "activate", accel_group, GDK_KEY_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	opentool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(opentool), "document-open");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (opentool), "打开一个文件");
	g_signal_connect(G_OBJECT(opentool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-o打开");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), opentool, -1);

	save = gtk_menu_item_new_with_label ("保存");
	gtk_menu_shell_append (GTK_MENU_SHELL (filemenu), save);
	g_signal_connect(G_OBJECT(save), "activate", G_CALLBACK(shortcut_key_action), "ctrl-s保存");
	gtk_widget_add_accelerator (save, "activate", accel_group, GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	savetool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(savetool), "document-save");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (savetool), "保存当前文件");
	g_signal_connect(G_OBJECT(savetool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-s保存");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), savetool, -1);

	saveas = gtk_menu_item_new_with_label ("另存为");
	gtk_menu_shell_append (GTK_MENU_SHELL (filemenu), saveas);
	g_signal_connect(G_OBJECT(saveas), "activate", G_CALLBACK(shortcut_key_action), "shift-s另存为");
	gtk_widget_add_accelerator (saveas, "activate", accel_group, GDK_KEY_s, GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
	/*  查网上说GDK_MOD1_MASK表示ctrl+shift组合,但经试验是没有结果的,还不知如何实现,暂时只用shift+s代替  */
	saveastool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(saveastool), "document-save-as");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (saveastool), "另外保存当前文件");
	g_signal_connect(G_OBJECT(saveastool), "clicked", G_CALLBACK(shortcut_key_action), "shift-s另存为");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), saveastool, -1);

	separator_menu = gtk_separator_menu_item_new ();
	/*  创建分隔条separator_menu,就是纯粹一条横线而已  */
	gtk_menu_shell_append (GTK_MENU_SHELL (filemenu), separator_menu);

	quit = gtk_menu_item_new_with_label ("退出");
	gtk_menu_shell_append (GTK_MENU_SHELL (filemenu), quit);
	g_signal_connect(G_OBJECT(quit), "activate", G_CALLBACK(gtk_main_quit), NULL);
	gtk_widget_add_accelerator (quit, "activate", accel_group, GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	quittool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(quittool), "application-exit");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (quittool), "退出本程序");
	g_signal_connect(G_OBJECT(quittool), "clicked", G_CALLBACK(gtk_main_quit), NULL);
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), quittool, -1);

	separator_tool = gtk_separator_tool_item_new ();
	/*  创建分隔条separator_tool,就是纯粹一条坚线而已  */
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), separator_tool, -1);

	editmenu = gtk_menu_new ();
	gtk_menu_item_set_submenu (GTK_MENU_ITEM (edit), editmenu);
	copy = gtk_menu_item_new_with_label ("复制");
	gtk_menu_shell_append (GTK_MENU_SHELL (editmenu), copy);
	g_signal_connect(G_OBJECT(copy), "activate", G_CALLBACK(shortcut_key_action), "ctrl-c复制");
	gtk_widget_add_accelerator (copy, "activate", accel_group, GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	copytool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(copytool), "edit-copy");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (copytool), "复制内容");
	g_signal_connect(G_OBJECT(copytool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-c复制");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), copytool, -1);

	cut = gtk_menu_item_new_with_label ("剪切");
	gtk_menu_shell_append (GTK_MENU_SHELL (editmenu), cut);
	g_signal_connect(G_OBJECT(cut), "activate", G_CALLBACK(shortcut_key_action), "ctrl-x剪切");
	gtk_widget_add_accelerator (cut, "activate", accel_group, GDK_KEY_x, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	cuttool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(cuttool), "edit-cut");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (cuttool), "剪切内容");
	g_signal_connect(G_OBJECT(cuttool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-x剪切");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), cuttool, -1);

	paste = gtk_menu_item_new_with_label ("粘贴");
	gtk_menu_shell_append (GTK_MENU_SHELL (editmenu), paste);
	g_signal_connect(G_OBJECT(paste), "activate", G_CALLBACK(shortcut_key_action), "ctrl-v粘贴");
	gtk_widget_add_accelerator (paste, "activate", accel_group, GDK_KEY_v, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	pastetool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(pastetool), "edit-paste");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (pastetool), "粘贴内容");
	g_signal_connect(G_OBJECT(pastetool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-v粘贴");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), pastetool, -1);

	find = gtk_menu_item_new_with_label ("查找");
	gtk_menu_shell_append (GTK_MENU_SHELL (editmenu), find);
	g_signal_connect(G_OBJECT(find), "activate", G_CALLBACK(shortcut_key_action), "ctrl-f查找");
	gtk_widget_add_accelerator (find, "activate", accel_group, GDK_KEY_f, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	findtool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(findtool), "edit-find");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (findtool), "查找内容");
	g_signal_connect(G_OBJECT(findtool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-f查找");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), findtool, -1);

	replace = gtk_menu_item_new_with_label ("替换");
	gtk_menu_shell_append (GTK_MENU_SHELL (editmenu), replace);
	g_signal_connect(G_OBJECT(replace), "activate", G_CALLBACK(shortcut_key_action), "ctrl-h替换");
	gtk_widget_add_accelerator (replace, "activate", accel_group, GDK_KEY_h, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
	replacetool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(replacetool), "edit-find-replace");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (replacetool), "查找并替换内容");
	g_signal_connect(G_OBJECT(replacetool), "clicked", G_CALLBACK(shortcut_key_action), "ctrl-h替换");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), replacetool, -1);

	surfacemenu = gtk_menu_new ();
	/* 在二级菜单外观下,创建三级菜单字体和皮肤,三级菜单字体是检查菜单就可以多选,全选全不选只选一个也行,三级菜单皮肤是选择菜单只能多选一,三个选项中只能一个,点选一个就不能同时选另外两个 */
	gtk_menu_item_set_submenu (GTK_MENU_ITEM (surface), surfacemenu);
	font = gtk_menu_item_new_with_label ("字体");
	gtk_menu_shell_append (GTK_MENU_SHELL(surfacemenu), font);
	skin = gtk_menu_item_new_with_label ("皮肤");
	gtk_menu_shell_append (GTK_MENU_SHELL(surfacemenu), skin);
	
	fontmenu = gtk_menu_new ();
	gtk_menu_item_set_submenu (GTK_MENU_ITEM (font), fontmenu);
	font1 = gtk_check_menu_item_new_with_label ("blod黑体字");
	gtk_menu_shell_append (GTK_MENU_SHELL (fontmenu), font1);
	font2 = gtk_check_menu_item_new_with_label ("italics斜体字");
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font2), TRUE);
	/*  设置italics斜体字font2的默认状态是已经勾选了  */
	gtk_menu_shell_append (GTK_MENU_SHELL (fontmenu), font2);
	font3 = gtk_check_menu_item_new_with_label ("underline下划线");
	gtk_menu_shell_append (GTK_MENU_SHELL (fontmenu), font3);
	fontimage = gtk_image_new_from_icon_name ("format-text-bold", GTK_ICON_SIZE_MENU);
	/*  设置图片为format-text-bold和大小为GTK_ICON_SIZE_MENU  */
	fonttool = gtk_menu_tool_button_new (fontimage, NULL);
	/*  创建工具条按钮newtool,带有图片format-text-bold,不带有文字  */
	gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (fonttool), fontmenu);
	/* 设置工具条按钮菜单使用现有的fontmenu菜单 */
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (fonttool), "字体,可以多选");
	g_signal_connect(G_OBJECT(fonttool), "clicked", G_CALLBACK(shortcut_key_action), "字体");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), fonttool, -1);

	skinmenu = gtk_menu_new ();
	gtk_menu_item_set_submenu (GTK_MENU_ITEM (skin), skinmenu);
	skin1 = gtk_radio_menu_item_new_with_label (groupskin, "red红色");
	/* 创建皮肤skin1而且要与groupskin相关联,此时groupskin的值为NULL */
	groupskin = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (skin1));
	/* 将groupskin值设定为GTK_RADIO_MENU_ITEM (skin1) */
	gtk_menu_shell_append (GTK_MENU_SHELL (skinmenu), skin1);
	skin2 = gtk_radio_menu_item_new_with_label (groupskin, "green绿色");
	/* 创建皮肤skin2而且要与groupskin相关联,此时groupskin的值为skin1,之后创建的皮肤skin3都要与groupskin相关联,才能实现多选一的功能 */
	gtk_menu_shell_append (GTK_MENU_SHELL (skinmenu), skin2);
	skin3 = gtk_radio_menu_item_new_with_label (groupskin, "blue蓝色");
	/*gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (skin3), TRUE);*/
	gtk_menu_shell_append (GTK_MENU_SHELL (skinmenu), skin3);

	helpmenu = gtk_menu_new ();
	gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), helpmenu);
	helpf1 = gtk_menu_item_new_with_label ("帮助F1");
	gtk_menu_shell_append (GTK_MENU_SHELL (helpmenu), helpf1);
	g_signal_connect(G_OBJECT(helpf1), "activate", G_CALLBACK(shortcut_key_action), "F1帮助");
	gtk_widget_add_accelerator (helpf1, "activate", accel_group, GDK_KEY_F1, 0, GTK_ACCEL_VISIBLE);
	helpf1tool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(helpf1tool), "gtk-help");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (helpf1tool), "帮助文件说明书");
	g_signal_connect(G_OBJECT(helpf1tool), "clicked", G_CALLBACK(shortcut_key_action), "F1帮助");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), helpf1tool, -1);

	aboutf7 = gtk_menu_item_new_with_label ("关于我F7");
	gtk_menu_shell_append (GTK_MENU_SHELL (helpmenu), aboutf7);
	g_signal_connect(G_OBJECT(aboutf7), "activate", G_CALLBACK(shortcut_key_action), "F7关于我");
	gtk_widget_add_accelerator (aboutf7, "activate", accel_group, GDK_KEY_F7, 0, GTK_ACCEL_VISIBLE);
	aboutf7tool = gtk_tool_button_new (NULL, NULL);
	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(aboutf7tool), "gtk-about");
	gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (aboutf7tool), "关于本程序的自我说明");
	g_signal_connect(G_OBJECT(aboutf7tool), "clicked", G_CALLBACK(shortcut_key_action), "F7关于我");
	gtk_toolbar_insert (GTK_TOOLBAR(toolbar), aboutf7tool, -1);
		
	gtk_widget_show_all (window);
	/*  显示构件窗口包括所有构件  */
	gtk_main ();
	/*  进入主循环,等待信号(鼠标键盘)输入  */
	return 0;
}

效果图如下
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值