鱼C论坛

 找回密码
 立即注册
查看: 6419|回复: 1

[技术交流] C语言GUI程序设计-GTK图文系列-按钮

[复制链接]
发表于 2014-11-1 14:14:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 G0398 于 2014-11-1 14:17 编辑

前几节讲完了常用的布局部件,这一节来看看常用的按钮。

按钮是GUI应用程序中处理用户交互最常用的部件了,按钮又分为多种形态来满足GUI程序设计的需求。

gtk_button.png

(示例资源: 1.png )

几种按钮部件通过Grid布局放入窗口中,包括:GtkButton,GtkToggleButton,GtkCheckButton,GtkSwitchButton,GtkLinkButton,GtkVolumeButton,GtkRadioButton,GtkFileChooseButton,GtkFontButton,GtkColorButton,GtkSpinButton。
文件选择框按钮,字体选择框和

例程代码:
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>

int window_width = 500;
int window_height = 200;

void button_click(GtkButton *button,gpointer data)
{
    printf("button clicked!\n");
}
void button_enter(GtkButton *button,gpointer data)
{
    printf("button enter!\n");
}
void button_leave(GtkButton *button,gpointer data)
{
    printf("button leave!\n");
}
void button_pressed(GtkButton *button,gpointer data)
{
    printf("button pressed!\n");
}
void button_released(GtkButton *button,gpointer data)
{
    printf("button released!\n");
}
void button_toggled(GtkToggleButton *button,gpointer data)
{
    gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));

    if(state)
    {
        printf("toggle button pressed!\n");
    }
    else
    {
        printf("toggle button unpressed!\n");
    }
}
void button_checked(GtkToggleButton *button,gpointer data)
{
    gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));

    if(state)
    {
        printf("check button checked!\n");
    }
    else
    {
        printf("check button unchecked!\n");
    }
}
void button_switch(GtkSwitch *button,gpointer data)
{
    gboolean state = gtk_switch_get_active(GTK_SWITCH(button));

    if(state)
    {
        printf("switch on!\n");
    }
    else
    {
        printf("switch off!\n");
    }
}
void button_volume_value_change(GtkScaleButton *button,gpointer data)
{
    gdouble value = gtk_scale_button_get_value(GTK_SCALE_BUTTON(button));
    printf("volume value changed:%lf\n",value);
}
void file_chooser_selection_changed(GtkFileChooser *chooser,gpointer data)
{
    gchar* file_name = gtk_file_chooser_get_filename(chooser);

    printf("selected file is:%s\n",file_name);
}
void font_choose(GtkFontButton *button,gpointer data)
{
    gchar* font_name = gtk_font_button_get_font_name(button);

    printf("selected font is:%s\n",font_name);
}
void color_choose(GtkColorButton *button,gpointer data)
{
    GdkRGBA *color;

    color = (GdkRGBA *)malloc(sizeof(GdkRGBA *));

    gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(button),color);

    printf("color rgb(%lf,%lf,%lf)\n",color->red,color->green,color->blue);

    free(color);
}
void spin_value_change(GtkSpinButton *button,gpointer data)
{
    gint value = gtk_spin_button_get_value_as_int(button);

    printf("spin value is:%d\n", value);
}
int main(int argc,char *argv[])
{
    int row = 5,column = 4,i,j;
    GtkWidget *window,*grid;
    GtkWidget *normal_button,*toggle_button,*check_button,*switch_button;
    GtkWidget *link_button,*volume_button,*radio_button_1,*radio_button_2;
    GtkWidget *file_choose_button,*font_button,*color_button,*spin_button;
    GtkWidget *image_button,*image;

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

    grid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(window), grid);

    gtk_grid_set_row_spacing (GTK_GRID(grid), 20);
    gtk_grid_set_column_spacing(GTK_GRID(grid),30);

    for(i=0;i<row;i++)
    {
        gtk_grid_insert_row(GTK_GRID(grid),0);
    }
    for(j=0;j<column;j++)
    {
        gtk_grid_insert_column(GTK_GRID(grid),0);
    }

    normal_button = gtk_button_new_with_label("normal button");
    g_signal_connect(GTK_WIDGET(normal_button),"clicked",G_CALLBACK(button_click),NULL);
    g_signal_connect(GTK_WIDGET(normal_button),"enter",G_CALLBACK(button_enter),NULL);
    g_signal_connect(GTK_WIDGET(normal_button),"leave",G_CALLBACK(button_leave),NULL);
    g_signal_connect(GTK_WIDGET(normal_button),"pressed",G_CALLBACK(button_pressed),NULL);
    g_signal_connect(GTK_WIDGET(normal_button),"released",G_CALLBACK(button_released),NULL);

    toggle_button = gtk_toggle_button_new_with_label("toggle button");
    g_signal_connect(GTK_WIDGET(toggle_button),"toggled",G_CALLBACK(button_toggled),NULL);

    check_button = gtk_check_button_new_with_label("choose it");
    g_signal_connect(GTK_WIDGET(check_button),"toggled",G_CALLBACK(button_checked),NULL);

    switch_button = gtk_switch_new();
    g_signal_connect(GTK_WIDGET(switch_button),"notify::active",G_CALLBACK(button_switch),NULL);

    link_button = gtk_link_button_new_with_label("http://www.gnome.org","link button");

    volume_button = gtk_volume_button_new();
    g_signal_connect(GTK_WIDGET(volume_button),"value-changed",G_CALLBACK(button_volume_value_change),NULL);

    radio_button_1 = gtk_radio_button_new_with_label(NULL,"radio 1");
    radio_button_2 = gtk_radio_button_new_with_label_from_widget(radio_button_1,"radio 2");

    file_choose_button = gtk_file_chooser_button_new("file choose",GTK_FILE_CHOOSER_ACTION_OPEN);
    g_signal_connect(GTK_WIDGET(file_choose_button),"selection-changed",G_CALLBACK(file_chooser_selection_changed),NULL);

    font_button = gtk_font_button_new();
    g_signal_connect(GTK_WIDGET(font_button),"font-set",G_CALLBACK(font_choose),NULL);

    color_button = gtk_color_button_new();
    g_signal_connect(GTK_WIDGET(color_button),"color-set",G_CALLBACK(color_choose),NULL);

    spin_button = gtk_spin_button_new_with_range(0,100,2);
    g_signal_connect(GTK_WIDGET(spin_button),"value-changed",G_CALLBACK(spin_value_change),NULL);

    image_button = gtk_button_new();
    image = gtk_image_new_from_file("1.png");
    gtk_button_set_image(GTK_BUTTON(image_button), image);

    gtk_grid_attach(GTK_GRID(grid),normal_button,1,1,1,1);
    gtk_grid_attach(GTK_GRID(grid),toggle_button,2,1,1,1);
    gtk_grid_attach(GTK_GRID(grid),check_button,3,1,1,1);
    gtk_grid_attach(GTK_GRID(grid),switch_button,4,1,1,1);

    gtk_grid_attach(GTK_GRID(grid),link_button,1,2,1,1);
    gtk_grid_attach(GTK_GRID(grid),volume_button,2,2,1,1);
    gtk_grid_attach(GTK_GRID(grid),radio_button_1,3,2,1,1);
    gtk_grid_attach(GTK_GRID(grid),radio_button_2,4,2,1,1);

    gtk_grid_attach(GTK_GRID(grid),file_choose_button,1,3,1,1);
    gtk_grid_attach(GTK_GRID(grid),font_button,2,3,1,1);
    gtk_grid_attach(GTK_GRID(grid),color_button,3,3,1,1);
    gtk_grid_attach(GTK_GRID(grid),spin_button,4,3,1,1);

    gtk_grid_attach(GTK_GRID(grid),image_button,1,4,1,1);

    gtk_window_set_title(GTK_WINDOW(window),"hello fishc - GtkButton");

    gtk_widget_show_all(window);
    gtk_main ();

    return 0;
}

GtkButton

GtkButton是所有按钮的“父类”,可以显示文本,文本+图片或图片。按钮可以处理的信号有clicked,enter,leave,pressed,released,分别是按钮点击,光标移入,光标移出,按钮按下,按钮释放。

gtk_button_set_image函数用来设置按钮显示的图片,第二个参数为GtkImage,通过gtk_image_new_from_file("图片文件名")函数创建。

GtkToggleButton

GtkToggleButton是一个可以保持按下状态的按钮,可以通过注册 toggled 信号接收状态改变通知,通过gtk_toggle_button_get_active函数获取状态。

GtkCheckBox

GtkCheckBox为复选按钮,可以用来选择多个选项。由于它“继承”于GtkToggleButton,所以可以通过注册 toggled 信号来获取选中状态改变通知。

GtkSwitchButton

GtkSwitchButton是一个开关按钮,用来切换开关状态,和android中的Switch控件类似。注册 notify::active 信号接收状态改变通知,通过
gtk_switch_get_active函数获取当前状态。

GtkLinkButton

GtkLinkButton是一个用来打开超链接的部件,以蓝色带下划线文本方式呈现,无边框,但是在Windows系统下点击打开超链接失败,提示没有注册处理程序。
一步一步跟下去发现Windows系统下会调用AssocQueryString这个api,第三个参数需要传入一个决定root key (注册表中)的字符串,msdn中说明的参数类型有四种,没有包括MIME,但是在GTK中却传入了text/html这个MIME类型,所以导致该功能失效。估计红帽的程序员在Windows下也抓瞎。

GtkVolumeButton

GtkVolumnButton是一个调节音量的按钮,可以通过注册 value-changed 信号获取值改变通知,其值为0-1的浮点数。

GtkRadioButton

GtkRadioButton是一个单选按钮,用来为用户提供可枚举的选项。
gtk_radio_button_new_with_label_from_widget函数用来添加GrkRadioButton,并于传入参数归为一组。单选按钮只有是一组时才会出现 单选 的效果。

GtkFileChooserButton

GtkFileChooserButton为文件选择按钮,点击后弹出文件选择框。
效果:
gtk_file_chooser.png


通过gtk_file_chooser_button_new函数创建,创建时可以设置选择框的行为,例如:打开文件,保存文件,选择文件夹,创建文件夹等。
注册 selection-change 信号获取选择文件改变通知,通过gtk_file_chooser_get_filename函数获取选择文件的路径。

GtkFontButton

GtkFontButton提供字体选择功能,点击后弹出字体选择框,还可以设置所选字体大小。
效果:
gtk_font_chooser.png

注册 font-set 信号通知获取字体设置通知,gtk_font_button_get_font_name 函数用来获取用户设置的字体和字体大小。

例如:
Sans 16
选择了Sans字体,字号为16号。

GtkColorButton

GtkColorButton为颜色选择按钮,点击弹出颜色选择框。
效果:
gtk_color_chooser.png

注册 color-set 信号获取颜色选择通知,通过gtk_color_button_get_color函数获取选择的颜色,获取结果为GdkRGBA结构。
typedef struct {
  gdouble red;
  gdouble green;
  gdouble blue;
  gdouble alpha;
} GdkRGBA;
颜色的r g b 分量都为0到1的浮点数。

GtkSpainButton

GtkSpinButton提供一个数据设置的微调按钮,可以用来设置整形或浮点型数据。

gtk_spin_button_new_with_range函数用来初始化,可以设置最小值,最大值和步长。
注册 value-changed 信号获取数值改变通知,通过gtk_spin_button_get_value_as_int 函数获取int型的数值。

常用的按钮就讲解这么多,下一讲讲解Gtk中的菜单。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-1-22 14:43:52 | 显示全部楼层
带图片那个按钮  为什么有4个白边, 那4个白边不能去掉吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-26 18:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表