GTK编程基础----菜单选项

相关代码可以在github上下载:https://github.com/jin13417/GTK

 

菜单控件

创建菜单栏和子菜单时要用到三种构件:
• 一个菜单项(menu item),就是用户要选择的东西,比如,"Save"
• 一个菜单(menu),作为菜单项的容器。
• 一个菜单栏(menubar),是各个单独菜单的容器。

下面是创建菜单控件的一般步骤:

• 用 gtk_menu_new() 创建一个新的菜单
• 多次调用 gtk_menu_item_new() 创建每个你想在你的菜单上出现的菜单项。并使用 gtk_menu_append() 将每个新的菜单项放到
菜单上。
• 用 gtk_menu_item_new() 创建一个菜单项。这将是菜单的根(root),上面显示的文本将自己出现在菜单栏上。
• 用 gtk_menu_item_set_submenu() 将菜单绑定到根菜单项(就是上一步创建的那个)。
• 用 gtk_menu_bar_new 创建一个新的菜单栏。在一个菜单栏上创建一系列菜单时这步只要做一次就行了。
• 用 gtk_menu_bar_append() 将根菜单项放到菜单栏上。

 

创建一个弹出菜单和上面的几乎是一样,只是在设置回调函数时,如下:

g_signal_connect_swapped (G_OBJECT (widget), "event",
                              G_CALLBACK (handler),
                              G_OBJECT (menu));
 

其中widget是你要绑定到的构件,handler是处理函数,而menu是一个用 gtk_menu_new() 创建的菜单。它可以是一个也被菜单栏弹出的菜单。

看下面具体的例子:

/*File:menu_item.c
 *Date:2013-11-23
 *Author:sjin
 *Mail:413977243@qq.com
 */

#include <gtk/gtk.h>
#include <stdio.h>

static void menuitem_response(gchar *string)
{
    printf("%s\n",string);
}

static int button_press(GtkWidget *widget,GdkEvent *event)
{
    if(event->type == GDK_BUTTON_PRESS){
        GdkEventButton *bevent = (GdkEventButton *)event;
        gtk_menu_popup(GTK_MENU(widget),NULL,NULL,NULL,NULL,bevent->button,bevent->time);
        /*告诉调用代码我们已经处理这个事件,*/
        return TRUE;
    }
    /*else  未处理*/
    return FALSE;
}

gint delete_event( GtkWidget *widget,GdkEvent  *event,gpointer   data )
{
    /* 如果你的 "delete_event" 信号处理函数返回 FALSE,GTK 会发出 "destroy" 信号。
     * 返回 TRUE,你不希望关闭窗口。
     * 当你想弹出“你确定要退出吗?”对话框时它很有用。*/
    g_print ("delete event occurred\n");
    /* 改 TRUE 为 FALSE 程序会关闭,关闭时调用destroy()。*/
    return FALSE;
}
/* 另一个回调函数 */
void destroy( GtkWidget *widget,gpointer   data )
{
    gtk_main_quit ();
}
int main( int   argc, char *argv[] )
{
    /* GtkWidget 是构件的存储类型 */
    GtkWidget *window;
    GtkWidget *menu;
    GtkWidget *menu_bar;
    GtkWidget *root_menu;
    GtkWidget *menu_items;
    GtkWidget *vbox;
    GtkWidget *button;
    char buf[128];
    int i;
    
    /* 这个函数在所有的 GTK 程序都要调用。参数由命令行中解析出来并且送到该程序中*/
    gtk_init (&argc, &argv);
        /* 创建一个新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    /*设置窗口标题*/
    gtk_window_set_title(GTK_WINDOW(window),"My first program helloworld!");
    
    /* 当窗口收到 "delete_event" 信号 (这个信号由窗口管理器发出,通常是“关闭”
     * 选项或是标题栏上的关闭按钮发出的),我们让它调用在前面定义的 delete_event() 函数。
     * 传给回调函数的 data 参数值是 NULL,它会被回调函数忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",G_CALLBACK (delete_event), NULL);
    
    /* 在这里我们连接 "destroy" 事件到一个信号处理函数。  
     * 对这个窗口调用 gtk_widget_destroy() 函数或在 "delete_event" 回调函数中返回 FALSE 值
     * 都会触发这个事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",G_CALLBACK (destroy), NULL);
    
    /* 设置窗口边框的宽度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    
   /*创建窗口宽度*/
    gtk_widget_set_size_request(GTK_WIDGET(window),200,100);

    /***********************
     * 初始化菜单构件
     * 记住这里永远不要用gtk_widget_show()函数来显示菜单控件
     * 这个是包含菜单项的菜单,运行程序时点击会弹出来
     **********************/
    menu = gtk_menu_new();

    /*****************××××××××××
     *
     *
     * *********************/
    for(i = 0; i < 3; i++){
        /*将名称复制到buf*/
        sprintf(buf,"undetmenu-%d",i);

        /*创建一个菜单项*/
        menu_items = gtk_menu_item_new_with_label(buf);

        /*将它添加到菜单*/
        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_items);

        /*当菜单被选中时的回调函数*/
        g_signal_connect_swapped(G_OBJECT(menu_items),"activate",G_CALLBACK(menuitem_response),g_strdup(buf));

        /*显示构件*/
        gtk_widget_show(menu_items);
    }

    /*******************************
     *这个是根菜单,将成为现实在菜单栏上的标签
     *这里不会附上信号处理函数,因为它只是在被按下时弹出的其余的菜单
     *******************************/

    root_menu = gtk_menu_item_new_with_label("根菜单");
    gtk_widget_show(root_menu);

    /****************************
     *指定想要穿件的menu成为根菜单
     ***************************/

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu),menu);

    /*将一个菜单和一个按钮放到纵向盒子里面*/
    vbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(window),vbox);
    gtk_widget_show(vbox);

    /********************************
     *创建一个菜单栏,并添加到主窗口
     * *****************************/
    menu_bar = gtk_menu_bar_new();
    gtk_box_pack_start(GTK_BOX(vbox),menu_bar,FALSE,FALSE,2);
    gtk_widget_show(menu_bar);

    button = gtk_button_new_with_label("点击");
    g_signal_connect_swapped(G_OBJECT(button),"event",G_CALLBACK(button_press),menu);
    gtk_box_pack_end(GTK_BOX(vbox),button,TRUE,TRUE,2);
    gtk_widget_show(button);

    /**************************
     *最后把惨淡想添加到菜单栏上
     * ***************************/
    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),root_menu);

    gtk_widget_show(window);
    gtk_main ();
    return 0;
}
 

下面是利用gtk_item_factory来实现菜单选项:

/*******************************
 *使用套件生成菜单方式
 *gtk_item_factory
 **********************/

/*File:menu_item2.c
 *Date:2014-03-23
 *Author:sjin
 *Mail:413977243@qq.com
 */


#include <gtk/gtk.h>
#include <stdio.h>

/*必要的回调函数*/
static void print_hello(GtkWidget *w,gpointer data)
{
    g_message("Hello,World!\n");
}

/****************************************
 * 这是用来生成新惨淡的GtkItemFactoryEntry结构
 * 第一项 菜单路径 下划线后字母指出惨淡打开的快捷键
 * 第二项:这个条目的快捷键
 * 第三项:回调函数
 * 第四项,回调动作
 * 第五项:项类型用
 *         NULL   -> "Item"
 *         ""        "Item"
 *         "<Title>"  标题
 *         "<Item>"   创建一个简单的项
 *         "<CheckItem>" 创建一个检查项
 *         "<ToggleItem>" 创建一个开关项
 *         "<RadioItem>" 创建一个选择项
 *         <path>     选择项链接到的路径
 *         "<Separator>" 分割线
 *         "Branch"    创建一个包含子项的项
 *         "LastBranch" 创建一个右对齐的分支
 *************************************/

static GtkItemFactoryEntry menu_items[] = {
    {"/_File", NULL, NULL,0,"<Branch>"},
    {"/File/_New", "<control>N", print_hello,0,NULL},
    {"/File/_Open", "<control>O", print_hello,0,NULL},
    {"/File/_Save", "<control>S" ,print_hello,0,NULL},
    {"/File/Save _As", NULL,NULL,0,NULL},
    {"/File/sepl", NULL,NULL,0,"<Separator>"},
    {"/File/Quit", "<control>Q", gtk_main_quit,0,NULL},
    {"/_Options", NULL,NULL,0,"<Branch>"},
    {"/Options/Test", NULL,NULL,0,NULL},
    {"/_Help", NULL,NULL,0,"<LastBranch>"},
    {"/Help/About", NULL,NULL,0,NULL},
};


void get_main_menu(GtkWidget *window,GtkWidget **menu_bar)
{
    GtkItemFactory *item_factory;
    GtkAccelGroup *accel_group;
    gint nmenu_items = sizeof(menu_items)/sizeof(menu_items[0]);

    accel_group = gtk_accel_group_new();

    /****************************
     *这个函数初始化套件
     *参数1:菜单类型-
     *参数2:菜单路径 
     *参数3:指向一个gtk_accel_group 的指针
     * *****************************/

    item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR,"<main>",accel_group);
    
    /*生成菜单项,把数组里想的数量,数组自身,和菜单项的任意
     * 回调函数以此传递给套件*/
    gtk_item_factory_create_items(item_factory,nmenu_items,menu_items,NULL);

    /*把新的加速组绑定到窗口*/
    gtk_window_add_accel_group(GTK_WINDOW(window),accel_group);

    if(menu_bar){
        /*返回套件已经创建的菜单栏*/
        *menu_bar = gtk_item_factory_get_widget(item_factory,"<main>");
    }

}

gint delete_event( GtkWidget *widget,GdkEvent  *event,gpointer   data )
{
    /* 如果你的 "delete_event" 信号处理函数返回 FALSE,GTK 会发出 "destroy" 信号。
     * 返回 TRUE,你不希望关闭窗口。
     * 当你想弹出“你确定要退出吗?”对话框时它很有用。*/
    g_print ("delete event occurred\n");
    /* 改 TRUE 为 FALSE 程序会关闭,关闭时调用destroy()。*/
    return TRUE;
}
/* 另一个回调函数 */
void destroy( GtkWidget *widget,gpointer   data )
{
    gtk_main_quit ();
}
int main( int   argc, char *argv[] )
{
    /* GtkWidget 是构件的存储类型 */
    GtkWidget *window;
    GtkWidget *menu_bar;
    GtkWidget *vbox;
    
    /* 这个函数在所有的 GTK 程序都要调用。参数由命令行中解析出来并且送到该程序中*/
    gtk_init (&argc, &argv);
        /* 创建一个新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    /*设置窗口标题*/
    gtk_window_set_title(GTK_WINDOW(window),"My first program helloworld!");
    
    /* 当窗口收到 "delete_event" 信号 (这个信号由窗口管理器发出,通常是“关闭”
     * 选项或是标题栏上的关闭按钮发出的),我们让它调用在前面定义的 delete_event() 函数。
     * 传给回调函数的 data 参数值是 NULL,它会被回调函数忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",G_CALLBACK (delete_event), NULL);
    
    /* 在这里我们连接 "destroy" 事件到一个信号处理函数。  
     * 对这个窗口调用 gtk_widget_destroy() 函数或在 "delete_event" 回调函数中返回 FALSE 值
     * 都会触发这个事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",G_CALLBACK (destroy), NULL);
    
    /* 设置窗口边框的宽度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    
   /*创建窗口宽度*/
    gtk_widget_set_size_request(GTK_WIDGET(window),200,100);


    vbox = gtk_vbox_new(FALSE,1);
    gtk_container_add(GTK_CONTAINER(window),vbox);
    gtk_widget_show(vbox);

    get_main_menu(window,&menu_bar);
    gtk_box_pack_start(GTK_BOX(vbox),menu_bar,FALSE,TRUE,0);
    gtk_widget_show(menu_bar);


    gtk_widget_show(window);
    gtk_main ();
    return 0;
}

 

 问题:在运行后无法将菜单栏显示出来的的问题?

            运行程序需要ROOT权限。具体原因不清楚。。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 要进行gtk-doc-tools的离线安装,您需要以下步骤。 1. 下载gtk-doc-tools的源代码包。您可以从Gtk官方网站或其他可靠的源进行下载。确保下载对应于您操作系统和版本的正确包。 2. 在您的计算机上解压源代码包。您可以选择将其解压到任意位置,例如您的主文件夹或者/opt目录。解压后,您将会得到一个包含gtk-doc-tools的文件夹。 3. 打开终端,并切换到解压后的文件夹中。 4. 运行以下命令以配置gtk-doc-tools的安装选项: ``` ./configure ``` 该命令将会检查您的系统环境,并根据您的配置进行预准备。 5. 运行以下命令以编译gtk-doc-tools: ``` make ``` 这将会开始编译gtk-doc-tools。这个过程可能需要一些时间,请耐心等待。 6. 运行以下命令以安装gtk-doc-tools: ``` sudo make install ``` 这个命令将会将gtk-doc-tools安装到您的操作系统中。请确保您具有足够的权限来安装软件。 7. 安装完成后,您可以通过在终端中运行gtk-doc-check命令来验证安装是否成功。如果安装成功,您将会看到相关信息。 通过以上步骤,您可以离线安装gtk-doc-tools。请注意,由于系统配置和版本的差异,可能会影响安装过程。 ### 回答2: 要离线安装gtk-doc-tools,您需要进行以下步骤: 1. 首先,您需要下载gtk-doc-tools的离线安装包。您可以在gtk-doc-tools官方网站或其他可信的软件下载网站上找到这个安装包。确保下载的安装包与您系统的架构和版本相匹配。 2. 在下载完安装包后,将其解压缩到您想要安装gtk-doc-tools的目录。您可以选择将其解压缩到系统的默认目录,或者根据个人喜好选择其他目录。 3. 打开终端(Terminal)并导航到解压缩的gtk-doc-tools目录。 4. 在终端中,输入以下命令以开始安装过程: ``` ./configure make make install ``` 这些命令将配置安装环境,并编译和安装gtk-doc-tools。 5. 安装完成后,您可以通过运行以下命令来验证gtk-doc-tools是否成功安装: ``` gtkdoc-scan --version ``` 如果成功安装,您将看到gtk-doc-tools的版本信息。 请注意,离线安装gtk-doc-tools可能需要一些先决条件,例如GLib、Make、GCC等。如果您在安装过程中遇到依赖错误,请根据错误消息安装缺失的依赖项。 总之,通过下载gtk-doc-tools的离线安装包,解压缩并使用终端进行安装,您可以离线安装gtk-doc-tools。请确保您在安装过程中满足所有的依赖项和系统要求。 ### 回答3: gtk-doc-tools是一组用于生成GTK+应用程序文档的工具集。如果需要进行离线安装,可以按照以下步骤进行操作: 1. 首先,将gtk-doc-tools的源代码下载到本地。可以通过官方网站或者其他可靠的源代码仓库获取到最新的源代码包。下载源代码包后,解压缩到指定目录。 2. 进入解压缩后的目录,使用终端进入该目录。 3. 在终端中执行以下命令来安装gtk-doc-tools之前的依赖包:sudo apt-get install autoconf automake libtool 4. 在终端中执行以下命令来配置gtk-doc-tools的安装选项:./configure --prefix=/usr 这里的"--prefix=/usr"参数指定了gtk-doc-tools安装的目标路径,可以根据需要进行调整。 5. 配置完成后,执行make命令来编译gtk-doc-tools。这个过程可能需要一些时间,具体取决于您的计算机性能。 6. 编译完成后,执行sudo make install命令来安装gtk-doc-tools。这个命令将会将gtk-doc-tools的文件复制到指定的安装目录。 7. 安装完成后,可以在终端中执行gtkdocize命令来验证gtk-doc-tools是否已经成功安装。如果终端返回了gtkdocize的版本信息,则表示安装成功。 至此,gtk-doc-tools已经成功进行了离线安装。你可以在终端中使用gtk-doc-tools来生成GTK+应用程序的文档,为开发和使用这些应用程序提供参考和帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值