GTK+(2)--窗口中添加五脏六腑

在我们第一讲当中的窗口中,我们仅仅就是学习了如何使用GTK+创建一个空白的窗口,但是仅仅一个空白窗口是没有用的,我们总是需要设置窗口的属性和向窗口中添加一些子控件,包括应用程序的图标,菜单,工具栏等等内容.

下面的一段程序是设置我们的窗口的一些属性,包括设置窗口的标题,窗口的大小,窗口在屏幕中的位置等等属性.下面看一下代码:

#include <gtk/gtk.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
    GtkWidget *window;
    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  //创建新的窗口
    //设置窗口的标题
    gtk_window_set_title(GTK_WINDOW(window),"bobo_GTK_Hello");
    //设置用户是否可以重新更改窗口的大小
    gtk_window_set_resizable(GTK_WINDOW(window),TRUE);  //可以更改大小
    //gtk_window_set_resizable(GTK_WINDOW(window),FALSE); //不可更改
    //获取当前window窗口能否改变大小
    gboolean canResize = gtk_window_get_resizable(GTK_WINDOW(window));

    //设置窗口的大小
    gtk_window_set_default_size(GTK_WINDOW(window),230,150);

    //设置窗口位置在屏幕中心
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    /**
     * 现在我们看一下gtk_window_set_position的函数原型
     * void gtk_window_set_position (GtkWindow *window,GtkWindowPosition position);
     * 而GtkWindowPosition是一个枚举类型的变量
     * typedef enum
     * { 
     *  GTK_WIN_POS_NONE,  //不产生任何影响
     *  GTK_WIN_POS_CENTER, //窗口被放置的屏幕中央
     *  GTK_WIN_POS_MOUSE, //窗口被放置在当前鼠标的位置
     *  GTK_WIN_POS_CENTER_ALWAYS, //当窗口改变大小之后也在屏幕中央
     *  GTK_WIN_POS_CENTER_ON_PARENT //在他父窗口的中央
     * } GtkWindowPosition;
     *
     *
     *
     */

    gtk_widget_show(window);
    //设置程序退出的信号
    g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

    gtk_main();
    return 0;
}

下面是这段程序的运行代码:

其中,那个设置退出信号我们后面会专门讲解.

下面我们学习一个窗口中,应用程序图标的制作.
先看下面为程序添加图标的代码:

#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar * filename)
{
    GdkPixbuf *pixbuf;
    GError *error = NULL;
    pixbuf = gdk_pixbuf_new_from_file(filename,&error);

    if(!pixbuf){
        fprintf(stderr,"%s
",error->message);
        g_error_free(error);
    }
    return pixbuf;
}
int main(int argc,char *argv[])
{
    GtkWidget *window;
    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  //创建新的窗口
    //设置窗口的标题
    gtk_window_set_title(GTK_WINDOW(window),"bobo_GTK_Hello");
    //设置用户是否可以重新更改窗口的大小
    gtk_window_set_resizable(GTK_WINDOW(window),TRUE);  //可以更改大小
    //gtk_window_set_resizable(GTK_WINDOW(window),FALSE); //不可更改
    //获取当前window窗口能否改变大小
    gboolean canResize = gtk_window_get_resizable(GTK_WINDOW(window));

    //设置窗口的大小
    gtk_window_set_default_size(GTK_WINDOW(window),230,150);

    //设置窗口位置在屏幕中心
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    /**
     * 现在我们看一下gtk_window_set_position的函数原型
     * void gtk_window_set_position (GtkWindow *window,GtkWindowPosition position);
     * 而GtkWindowPosition是一个枚举类型的变量
     * typedef enum
     * { 
     *  GTK_WIN_POS_NONE,  //不产生任何影响
     *  GTK_WIN_POS_CENTER, //窗口被放置的屏幕中央
     *  GTK_WIN_POS_MOUSE, //窗口被放置在当前鼠标的位置
     *  GTK_WIN_POS_CENTER_ALWAYS, //当窗口改变大小之后也在屏幕中央
     *  GTK_WIN_POS_CENTER_ON_PARE_POS_NONE,  //不产生NT //在他父窗口的中央
     * } GtkWindowPosition;
     *
     *
     *
     */
    //设置程序图标
    gtk_window_set_icon(GTK_WINDOW(window),create_pixbuf("bobo.png"));

    gtk_widget_show(window);
    //设置程序退出的信号
    g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

    gtk_main();
    return 0;
}

create_picbuf()函数的作用是从文件中读取图片文件,生成GdkPixbuf数据类型.下面我们看一下其中主要的函数
gdk_pixbuf_new_from_file()的定义.

GdkPixbuf * gdk_pixbuf_new_from_file (const char *filename, GError **error);
GdkPixbuf * gdk_pixbuf_new_from_file (const char *filename, GError **error);

意思就是:通过从文件中加载一个图像来创建一个新的pixbuf对象.文件的格式是自动检测的.如果返回值是NULL的话,error参数将会
被设置,可能的错误在GDK_PIXBUF_ERROR和G_FILE_ERROR域中.
​filename参数: 要被加载的文件的名称
​error参数:返回一个错误的位置
​返回值:将会返回一个新创建的pixbuf对象,并且该对象的引用数为1,或者是返回NULL如果发生下面的错误的话:文件无法打开,无法识别的 ​文件格式,没有足够的内存来加载该图片,或者是图片文件包含无效的数据

下面是程序的运行结果:

好了,对窗口的属性设置也了解的差不多了,现在我们设计一个小程序,学习向窗口中添加按钮等组件.

我们这个小程序向窗口中添加两个按钮和一个标签,标签的初始数为0,两个按钮分别控制标签中数字的增大和缩小.

下面请看一下实现的代码:

#include <gtk/gtk.h>
gint count = 0;
char buf[5];
void increase(GtkWidget *widget,gpointer label){
    count++;
    sprintf(buf,"%d",count);
    gtk_label_set_text(label,buf);
}
void decrease(GtkWidget *widget,gpointer label){
    count--;

    sprintf(buf,"%d",count);

    gtk_label_set_text(label,buf);
}
int main(int argc,char *argv[])
{
    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *frame;
    GtkWidget *plus;
    GtkWidget *minus;

    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title(GTK_WINDOW(window),"a little program");
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window),250,180);

    frame = gtk_fixed_new();

    gtk_container_add(GTK_CONTAINER(window),frame);

    plus = gtk_button_new_with_label("+");
    gtk_widget_set_size_request(plus,80,35);
    gtk_fixed_put(GTK_FIXED(frame),plus,50,20);

    minus = gtk_button_new_with_label("-");
    gtk_widget_set_size_request(minus,80,35);
    gtk_fixed_put(GTK_FIXED(frame),minus,50,80);

    label = gtk_label_new("0");
    gtk_fixed_put(GTK_FIXED(frame),label,190,58);

    gtk_widget_show_all(window);

    g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
    g_signal_connect(plus,"clicked",G_CALLBACK(increase),label);
    g_signal_connect(minus,"clicked",G_CALLBACK(decrease),label);
    gtk_main();
    return 0;
}

注意这个地方,g_signal_connect(plus,”clicked”,G_CALLBACK(increase),label);
我们把回调函数increase()和增加按钮绑定,这个地方我们把label作为回调函数的参数.这样,在回调函数increase()里面就能对label进行处理了.

对程序组件添加监听机制我打算在后面的讲解中专门拿出一节来讲解,主要讲解一下GTK+信号机制的原理以及使用方法。

下面是程序的运行结果:

posted @ 2015-05-22 00:04  陈洪波  阅读(192)  评论(0编辑  收藏  举报