Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6684161
  • 博文数量: 1159
  • 博客积分: 12444
  • 博客等级: 上将
  • 技术积分: 12570
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-13 21:34
文章分类

全部博文(1159)

文章存档

2016年(126)

2015年(350)

2014年(56)

2013年(91)

2012年(182)

2011年(193)

2010年(138)

2009年(23)

分类: C/C++

2011-11-21 09:13:38

http://jianjiaosun.blog.163.com/blog/static/136124486201102774447729/

本文将中“Menus and Toolbars in GTK+”一章中内容采用Glade进行界面设计的方法完成这一章中的例子,并且增加一些解释说明和学习体会。
    Glade进行图形化界面设计真的很给力,我以前也没有进行过图形界面相关的开发,虽然是学习过java,但是不是很喜欢,几乎都是混过去的,最近因为自 己想写一个东西,才开始学习使用glade进行界面设计,发现真的很方便。几乎会了写一个组件乐,其他的都是一样的。

一、简单的菜单
1、创建一个窗口
2、添加菜单
Gtk+/Glade编程(三) - unanao - unanao
 如上图:菜单就在“容器”中,鼠标指的地方。
 这个图时已经添加了“菜单”。
3、为“退出”菜单设置信号处理。
    获得对象:gtk_builder_get_object
   信号处理:g_signal_connect
    还以获得菜单对象会相对复杂一些,但是Gtk+真是好用,获得的方法居然和其它的组建一模一样,其实想一想这是很正常的事情,只有windows才喜欢复杂的东西,Open Source的思想是K.I.S.S原则。

图形界面设计完了,下面编写我们的GTK+程序:
#include

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+/Glade编程(三) - unanao - unanao
     开始写这个程序的时候,忘记写gtk_main()了,结果一执行就退出了,感觉添加菜单会复杂一些,在回宿舍的路上就想是吧return 0 写在gtk_main()的前面了,原来是忘记写gtk_main()了。晚上困了干什么都没效率,所以建议时刻保持充沛的精神,精力充沛的一天比熬夜的 2天更有效果。

二、图片菜单和快捷键
2.1 设置菜单的图片:
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
在“常规”中,打开“Custom label and image”,在下面有现则图片。

2.2 设置快捷键
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
 在“公共中”设置“加速键”,就可以使用Ctrl + q 退出窗口了。

2.3 Gtk+程序:
unanao@debian:~/Experiment/Programming/gui/menu-toolbars$ cat image-shortcuts.c
#include

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;
}
执行结果图:

Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
 
三、复选菜单
在要添加复选菜单处,右键选择:“Edit”,如“视图”:
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
 
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
 在“视图”上右键,选择“Add child check item item”。

在窗口中添加“Status bar”
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao

编写Gtk+代码:
unanao@debian:~/Experiment/Gui/menu-toolbars$ cat check-menu.c
#include

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;
}

 执行结果:
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
 四、工具条
    工具条为最长用的功能提供快速访问。
    这里省略加窗口、垂直框和菜单。
    添加工具条:
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
在toolbar上选择“Edit...”。
 
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
选择“Hierarchy” -->"添加",在“Edit Image” 的“保留ID”中选择需要添加的图片。

unanao@debian:~/Experiment/gui/menu-toolbars$ cat toolbar.c
/**
 * @file toolbar.c
 * @brief Simple Toolbar
 * @author unanao
 * @version 0.1
 * @date 2011-02-27
 */
#include

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;
}
运行结果:
Gtk+/Glade编程(三) 菜单和工具栏 - unanao - unanao
 
这样点击红色的关闭按钮,就可以关闭这个窗口。

五、撤销 重做
与四中添加“新建”中的方法相同,添加“撤销”和“重做”按钮。
编写代码:
unanao@debian:~/Experiment/gui/menu-toolbars$ cat undo-redo.c
/**
 * @file undo_redo.c
 * @brief Simple Toolbar
 * @author unanao
 * @version 0.1
 * @date 2011-02-28
 */
#include
#include
#include

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:。还没有想好解决办法。如果真的需要可以是这是用gtk+编程,而不是直接使用glade.


阅读(5522) | 评论(0) | 转发(6) |
给主人留下些什么吧!~~