本文将
http://zetcode.com/tutorials/gtktutorial/中“
Menus and Toolbars in GTK+
”一章中内容采用Glade进行界面设计的方法完成这一章中的例子,并且增加一些解释说明和学习体会。
Glade进行图形化界面设计真的很给力,我以前也没有进行过图形界面相关的开发,虽然是学习过java,但是不是很喜欢,几乎都是混过去的,最近因为自己想写一个东西,才开始学习使用glade进行界面设计,发现真的很方便。几乎会了写一个组件乐,其他的都是一样的。
一、简单的菜单
1、创建一个窗口
2、添加菜单
如上图:菜单就在“容器”中,鼠标指的地方。
这个图时已经添加了“菜单”。
3、为“退出”菜单设置信号处理。
获得对象:gtk_builder_get_object
信号处理:g_signal_connect
还以获得菜单对象会相对复杂一些,但是Gtk+真是好用,获得的方法居然和其它的组建一模一样,其实想一想这是很正常的事情,只有windows才喜欢复杂的东西,Open Source的思想是K.I.S.S原则。
图形界面设计完了,下面编写我们的GTK+程序:
#include <gtk/gtk.h>
gint main(int argc, char *argv[])
{
GtkWidget *window;
GtkBuilder *builder;
GtkWidget *quit_menu;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "simple-menu.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit_menu = GTK_WIDGET(gtk_builder_get_object(builder, "imagemenuitem5"));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(quit_menu, "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
编译:$ gcc -o simple-menu simple-menu.c `pkg-config --libs --cflags gtk+-2.0`
执行:$ ./simple-menu
开始写这个程序的时候,忘记写gtk_main()了,结果一执行就退出了,感觉添加菜单会复杂一些,在回宿舍的路上就想是吧return 0 写在gtk_main()的前面了,原来是忘记写gtk_main()了。晚上困了干什么都没效率,所以建议时刻保持充沛的精神,精力充沛的一天比熬夜的2天更有效果。
二、图片菜单和快捷键
2.1 设置菜单的图片:
在“常规”中,打开“Custom label and image”,在下面有现则图片。
2.2 设置快捷键
在“公共中”设置“加速键”,就可以使用Ctrl + q 退出窗口了。
2.3 Gtk+程序:
unanao@debian:~/Experiment/Programming/gui/menu-toolbars$ cat image-shortcuts.c
#include <gtk/gtk.h>
gint main(int argc, char *argv[])
{
GtkWidget *window;
GtkBuilder *builder;
GtkWidget *quit_menu;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "image-shortcuts.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit_menu = GTK_WIDGET(gtk_builder_get_object(builder, "quit_menu"));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(quit_menu, "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
执行结果图:
三、复选菜单
在要添加复选菜单处,右键选择:“Edit”,如“视图”:
在“视图”上右键,选择“Add child check item item”。
在窗口中添加“Status bar”
编写Gtk+代码:
unanao@debian:~/Experiment/Gui/menu-toolbars$ cat check-menu.c
#include <gtk/gtk.h>
void toggle_statusbar(GtkWidget *widget, gpointer *status_bar)
{
if (gtk_check_menu_item_get_active(widget))
{
gtk_widget_show(GTK_WIDGET(status_bar));
}
else
{
gtk_widget_hide(GTK_WIDGET(status_bar));
}
}
gint main(int argc, char *argv[])
{
GtkWidget *window;
GtkBuilder *builder;
GtkWidget *quit_menu;
GtkWidget *status_bar;
GtkWidget *tog_stat;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "image-shortcuts.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit_menu = GTK_WIDGET(gtk_builder_get_object(builder, "quit_menu"));
status_bar = GTK_WIDGET(gtk_builder_get_object(builder, "statusbar1"));
tog_stat = GTK_WIDGET(gtk_builder_get_object(builder, "checkstatus"));
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(quit_menu), "activate", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(tog_stat), "activate", G_CALLBACK(toggle_statusbar), status_bar);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
执行结果:
四、工具条
工具条为最长用的功能提供快速访问。
这里省略加窗口、垂直框和菜单。
添加工具条:
这样点击红色的关闭按钮,就可以关闭这个窗口。
五、撤销 重做
与四中添加“新建”中的方法相同,添加“撤销”和“重做”按钮。
编写代码:
unanao@debian:~/Experiment/gui/menu-toolbars$ cat undo-redo.c
/**
* @file undo_redo.c
* @brief Simple Toolbar
* @author unanao <sunjianjiao@gmai.com>
* @version 0.1
* @date 2011-02-28
*/
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
void undo_redo(GtkWidget *widget, gpointer item)
{
static int count = 2;
const char *name = gtk_widget_get_name(GTK_WIDGET(widget));
if (strcmp(name, "undo") == 0)
{
count--;
}
else if (strcmp(name, "redo") == 0)
{
count++ ;
}
else
{
exit(1); //If the name is not "undo" and "redo" , it means that parameter is error
}
if (count < 0)
{
gtk_widget_set_sensitive(widget, FALSE);
gtk_widget_set_sensitive(item, TRUE);
}
else if (count > 5)
{
gtk_widget_set_sensitive(widget, FALSE);
gtk_widget_set_sensitive(item, TRUE);
}
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkToolItem *quit;
GtkWidget *undo;
GtkToolItem *redo;
GtkBuilder *builder;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "toolbar.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit = GTK_TOOL_ITEM(gtk_builder_get_object(builder, "quit"));
undo = (gtk_builder_get_object(builder, "undo"));
redo = GTK_TOOL_ITEM(gtk_builder_get_object(builder, "redo"));
//undo = (gtk_builder_get_object(builder, "undo"));
//redo = (gtk_builder_get_object(builder, "redo"));
//printf below is used for debugging
printf("undo: %s\n", gtk_widget_get_name(undo));
printf("quit: %s\n", gtk_widget_get_name(quit));
printf("window: %s\n", gtk_widget_get_name(window));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//Attention please, here is "clicked"
g_signal_connect(quit, "clicked", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(undo, "clicked", G_CALLBACK(undo_redo), redo);
g_signal_connect(redo, "clicked", G_CALLBACK(undo_redo), undo);
gtk_main();
return 0;
}
gtk_widget_get_name存在一个bug:https://bugzilla.gnome.org/show_bug.cgi?id=614782。还没有想好解决办法。如果真的需要可以是这是用gtk+编程,而不是直接使用glade.
Glade进行图形化界面设计真的很给力,我以前也没有进行过图形界面相关的开发,虽然是学习过java,但是不是很喜欢,几乎都是混过去的,最近因为自己想写一个东西,才开始学习使用glade进行界面设计,发现真的很方便。几乎会了写一个组件乐,其他的都是一样的。
一、简单的菜单
1、创建一个窗口
2、添加菜单
这个图时已经添加了“菜单”。
3、为“退出”菜单设置信号处理。
获得对象:gtk_builder_get_object
信号处理:g_signal_connect
还以获得菜单对象会相对复杂一些,但是Gtk+真是好用,获得的方法居然和其它的组建一模一样,其实想一想这是很正常的事情,只有windows才喜欢复杂的东西,Open Source的思想是K.I.S.S原则。
图形界面设计完了,下面编写我们的GTK+程序:
#include <gtk/gtk.h>
gint main(int argc, char *argv[])
{
GtkWidget *window;
GtkBuilder *builder;
GtkWidget *quit_menu;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "simple-menu.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit_menu = GTK_WIDGET(gtk_builder_get_object(builder, "imagemenuitem5"));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(quit_menu, "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
编译:$ gcc -o simple-menu simple-menu.c `pkg-config --libs --cflags gtk+-2.0`
执行:$ ./simple-menu
二、图片菜单和快捷键
2.1 设置菜单的图片:
2.2 设置快捷键
2.3 Gtk+程序:
unanao@debian:~/Experiment/Programming/gui/menu-toolbars$ cat image-shortcuts.c
#include <gtk/gtk.h>
gint main(int argc, char *argv[])
{
GtkWidget *window;
GtkBuilder *builder;
GtkWidget *quit_menu;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "image-shortcuts.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit_menu = GTK_WIDGET(gtk_builder_get_object(builder, "quit_menu"));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(quit_menu, "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
执行结果图:
三、复选菜单
在要添加复选菜单处,右键选择:“Edit”,如“视图”:
在窗口中添加“Status bar”
编写Gtk+代码:
unanao@debian:~/Experiment/Gui/menu-toolbars$ cat check-menu.c
#include <gtk/gtk.h>
void toggle_statusbar(GtkWidget *widget, gpointer *status_bar)
{
if (gtk_check_menu_item_get_active(widget))
{
gtk_widget_show(GTK_WIDGET(status_bar));
}
else
{
gtk_widget_hide(GTK_WIDGET(status_bar));
}
}
gint main(int argc, char *argv[])
{
GtkWidget *window;
GtkBuilder *builder;
GtkWidget *quit_menu;
GtkWidget *status_bar;
GtkWidget *tog_stat;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "image-shortcuts.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit_menu = GTK_WIDGET(gtk_builder_get_object(builder, "quit_menu"));
status_bar = GTK_WIDGET(gtk_builder_get_object(builder, "statusbar1"));
tog_stat = GTK_WIDGET(gtk_builder_get_object(builder, "checkstatus"));
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(quit_menu), "activate", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(tog_stat), "activate", G_CALLBACK(toggle_statusbar), status_bar);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
工具条为最长用的功能提供快速访问。
这里省略加窗口、垂直框和菜单。
添加工具条:
在toolbar上选择“Edit...”。
选择“Hierarchy” -->"添加",在“Edit Image” 的“保留ID”中选择需要添加的图片。
unanao@debian:~/Experiment/gui/menu-toolbars$ cat toolbar.c
/**
* @file toolbar.c
* @brief Simple Toolbar
* @author unanao <sunjianjiao@gmai.com>
* @version 0.1
* @date 2011-02-27
*/
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkToolItem *quit;
GtkBuilder *builder;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "toolbar.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit = GTK_TOOL_ITEM(gtk_builder_get_object(builder, "quit"));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//Attention please, here is "clicked"
g_signal_connect(quit, "clicked", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
运行结果:
unanao@debian:~/Experiment/gui/menu-toolbars$ cat toolbar.c
/**
* @file toolbar.c
* @brief Simple Toolbar
* @author unanao <sunjianjiao@gmai.com>
* @version 0.1
* @date 2011-02-27
*/
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkToolItem *quit;
GtkBuilder *builder;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "toolbar.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit = GTK_TOOL_ITEM(gtk_builder_get_object(builder, "quit"));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//Attention please, here is "clicked"
g_signal_connect(quit, "clicked", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
运行结果:
五、撤销 重做
与四中添加“新建”中的方法相同,添加“撤销”和“重做”按钮。
编写代码:
unanao@debian:~/Experiment/gui/menu-toolbars$ cat undo-redo.c
/**
* @file undo_redo.c
* @brief Simple Toolbar
* @author unanao <sunjianjiao@gmai.com>
* @version 0.1
* @date 2011-02-28
*/
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
void undo_redo(GtkWidget *widget, gpointer item)
{
static int count = 2;
const char *name = gtk_widget_get_name(GTK_WIDGET(widget));
if (strcmp(name, "undo") == 0)
{
count--;
}
else if (strcmp(name, "redo") == 0)
{
count++ ;
}
else
{
exit(1); //If the name is not "undo" and "redo" , it means that parameter is error
}
if (count < 0)
{
gtk_widget_set_sensitive(widget, FALSE);
gtk_widget_set_sensitive(item, TRUE);
}
else if (count > 5)
{
gtk_widget_set_sensitive(widget, FALSE);
gtk_widget_set_sensitive(item, TRUE);
}
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkToolItem *quit;
GtkWidget *undo;
GtkToolItem *redo;
GtkBuilder *builder;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "toolbar.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
quit = GTK_TOOL_ITEM(gtk_builder_get_object(builder, "quit"));
undo = (gtk_builder_get_object(builder, "undo"));
redo = GTK_TOOL_ITEM(gtk_builder_get_object(builder, "redo"));
//undo = (gtk_builder_get_object(builder, "undo"));
//redo = (gtk_builder_get_object(builder, "redo"));
//printf below is used for debugging
printf("undo: %s\n", gtk_widget_get_name(undo));
printf("quit: %s\n", gtk_widget_get_name(quit));
printf("window: %s\n", gtk_widget_get_name(window));
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//Attention please, here is "clicked"
g_signal_connect(quit, "clicked", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(undo, "clicked", G_CALLBACK(undo_redo), redo);
g_signal_connect(redo, "clicked", G_CALLBACK(undo_redo), undo);
gtk_main();
return 0;
}
gtk_widget_get_name存在一个bug:https://bugzilla.gnome.org/show_bug.cgi?id=614782。还没有想好解决办法。如果真的需要可以是这是用gtk+编程,而不是直接使用glade.