嵌入式GTK+学习

嵌入式GTK+学习


GTK+( GIMP Toolkit ) 是一种函数库是用来帮助制作图形交互界面的。整个函数库都是由C 语言来编写的。同时GTK+ 也是嵌入式设计中最受欢迎的用于图形交互界面(GUI)设计的工具包之一。

创建空白窗口

#include <gtk/gtk.h>	//头文件
int main(int argc, char *argv[])
{
	gtk_init(&argc, &argv);	//初始化
	
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_widget_show(window);
	
	gtk_main();	//主事件循环
	return 0;
}

在这里插入图片描述

注:
直接使用gcc命令或者编写makefile来编译

编译的时候需要加上:

`pkg-config --cflags --libs gtk+-2.0`

( ` 为数字1键前面那个字符)
如:

gcc demo.c -o demo `pkg-config --cflags --libs gtk+-2.0`

解释:pkg-config --cflags --libs gtk±2.0
自动获得预处理参数,如宏定义,头文件位置
自动获得链接参数,如库及依赖的其他库位置,文件名及其他一些链接参数

GTK+程序的基本框架分析:

头文件 <gtk/gtk.h> 包含了GTK+中所有的控件、变量、函数和结构的声明。

1)gtk_init():这个函数必须在控件定义之前使用,参数由命令行中解析出来并且送到该程序中。主要作用是设立GTK+运行环境,自动完成一些必要的初始化工作。

2)创建GtkWidget窗口控件,并且让它显示出来。

3)gtk_main():程序运行停在这里等待事件(如键盘事件或鼠标事件)的发生,等待用户来操作窗口。这个函数在所有的GTK+程序都要调用。

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget 是GTK+控件类型,GtkWidget * 能指向任何控件的指针类型。
gtk_window_new()创建一个窗口并返回这个窗口的控件指针。
GTK_WINDOW_TOPLEVEL指明窗口的类型为最上层的主窗口,最常用。
git_widget_show(window);用来显示上一步创建的窗口控件。

窗口的详细设置

窗口的创建

GtkWidget *gtk_window_new(GtkWindowType type);
GtkWindowType是一个枚举,有两种情况
	GTK_WINDOW_TOPLEVEL:有边框
	GTK_WINDOW_POPUP:没边框

标题的设置

void gtk_window_set_title(GtkWindow *window, const gchar *title);

窗口大小的设置

void gtk_widget_set_size_request(GtkWidget *widget, gint width, gint height);

窗口伸缩设置(FALSE为不可伸缩)

void gtk_window_set_resizable(GtkWindow *window,gboolen resizable);

显示或隐藏所有控件

void gtk_widget_show_all(GtkWidget *widget);
void gtk_widget_hide_all(GtkWidget *widget);

窗口在显示器位置的设置

void gtk_window_set_position(GtkWindow *window, GtkWindowPosition position);

position常用四种情况:

GTK_WIN_POS_NONE:不固定
GTK_WIN_POS_CENTER:居中
GTK_WIN_POS_MOUSE:出现在鼠标位置
GTK_WIN_POS_CENTER_ALWAYS:窗口总是居中

例程

#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
	//初始化
	gtk_init(&argc, &argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"GTK+");
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//固定窗口大小
	gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
	//destroy和gtk_main_quit连接
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	//显示窗口全部控件
	gtk_widget_show_all(window);
	//隐藏窗口
	//gtk_widget_hide_all(window);
	
	//主事件循环
	gtk_main();
	return 0;
}

在这里插入图片描述

注意

在linux环境下编译时出现

(gtk_test:28720): GLib-GIO-CRITICAL **: g_dbus_connection_register_object: a

原因:用 su 切换到 root 后,root 使用的环境变量是使用 su 命令切换前的普通用户的环境变量。
解决方案:关闭当前命令行窗口,重新打开命令行窗口用

su - root

切换到root用户,再次进行编译运行。

窗口控件

控件是对数据和方法的封装。控件有自己的属性和方法,属性指控件的特征,方法指控件的一些常见功能。
控件分类:

  • 容器控件:可以容纳别的控件。一类智能容纳一个控件,如窗口、按钮;另一类可以容纳多个控件,如布局控件。
  • 非容器控件:不可以容纳别的控件,如标签、行编辑。

按钮窗口

创建一个带内容的按钮

GtkWidget *gtk_button_new_with_label(const gchar *label);

获取按钮上面的内容

const gchar *gtk_button_get_label(GtkButton *button);

把控件添加到窗口容器中

void gtk_container_add(GtkContainer *container, GtkWidget *widget);
container:容纳控件的容器;widget:要添加的控件

例程

#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
	gtk_init(&argc,&argv);

	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"GTK+");
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口边框的宽度
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//创建按钮,文本信息为Hello GTK+
	GtkWidget *button = gtk_button_new_with_label("Hello GTK+");
	//获取按钮内容
	const char *str = gtk_button_get_label(GTK_BUTTON(button));
	printf("str=%s\n",str);
	//将按钮放入窗口
	gtk_container_add(GTK_CONTAINER(window),button);
	//显示控件-逐个显示
	//gtk_widget_show(button);
	//gtk_widget_show(window);
	//显示窗口全部控件
	//destroy和gtk_main_quit连接
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	gtk_widget_show_all(window);

	//主事件循环
	gtk_main();
	return 0;
}

在这里插入图片描述

信号与回调函数

GTK+采用了信号与回调函数来处理窗口外部传来的事件、消息或信号。当这些发生时,程序自动调用其回调函数

窗口关闭时触发的常用信号:destroy,delete-event

操作按钮触发的常用信号:clicked,pressed,released

例程

#include <gtk/gtk.h>

//按钮按下的处理函数,gpointer 相当于 void *
void deal_pressed(GtkButton *button,gpointer user_data)
{
	//获取按钮的文本内容
	const gchar *text = gtk_button_get_label(button);
	//g_print()相当于C语言的printf(),gchar相当于char
	g_print("button_text = %s;user_data = %s\n",text,(gchar*)user_data);
}
int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);

	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"GTK+");
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口边框的宽度
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	//创建按钮
	GtkWidget *button = gtk_button_new_with_label("Hello GTK+");
	//将按钮放入窗口
	gtk_container_add(GTK_CONTAINER(window),button);
	//按钮按下,触发新建的deal_pressed函数
	g_signal_connect(button,"pressed",G_CALLBACK(deal_pressed),"is pressed");
	//显示窗口全部控件
	gtk_widget_show_all(window);

	gtk_main();
	return 0;
}

在这里插入图片描述

常用布局

布局:控件在整个窗口中的位置和尺寸
常用布局:

  • 水平布局:GtkHBox
  • 垂直布局:GtkVBox
  • 表格布局:GtkTable
  • 固定布局:GtkFixed

水平布局

创建水平布局容器

 GtkWidget *gtk_hbox_new(gboolean homogeneous,gint spacing);
  homogeneous:容器内控件是否均衡排放(大小一致-TRUE or FALSE)
  spacing:控件之间的间隔

添加控件到布局容器中

gtk_container_add(GtkContainer *container,GtkWidget *widget);

例程

#include<gtk/gtk.h>
int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口边框的宽度
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"horizontal layout");
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	//创建横向盒状容器
	GtkWidget *hbox = gtk_hbox_new(TRUE,10);
	//将横向盒装容器放入窗口
	gtk_container_add(GTK_CONTAINER(window),hbox);
	
	//创建button1
	GtkWidget *button1 = gtk_button_new_with_label("button1");
	//将button1放入横向盒装容器
	gtk_container_add(GTK_CONTAINER(hbox),button1);
	
	//创建button2
	GtkWidget *button2 = gtk_button_new_with_label("button2");
	//将button2放入横向盒装容器
	gtk_container_add(GTK_CONTAINER(hbox),button2);
	
	//创建button3
	GtkWidget *button3 = gtk_button_new_with_label("button3");
	//将button3放入横向盒装容器
	gtk_container_add(GTK_CONTAINER(hbox),button3);
	//显示窗口及控件
	gtk_widget_show_all(window);
	
	gtk_main();
	return 0;
}

在这里插入图片描述

垂直布局

创建垂直布局容器

GtkWidget *gtk_vbox_new(gboolean homogeneous,gint spacing);
 homogeneous:容器内控件是否均衡排放(大小一致-TRUE or FALSE)
 spacing:控件之间的间隔

添加控件到布局容器中

gtk_container_add(GtkContainer *container,GtkWidget *widget);

标签的创建

GtkWidget *gtk_label_new(const gchar *str);

设置标签内容

void gtk_label_set_text(GtkLabel *label,const gchar *str);

获取标签内容

const gchar *gtk_label_get_label(GtkLabel *label);

例程

#include <gtk/gtk.h>

#define PANGO_SCALE 1024
//编写函数设置label字体大小
void set_label_font_size(GtkLabel *label,int size)
{
	//字体指针
	PangoFontDescription *font;
	//参数为字体名字
	font = pango_font_description_from_string("");
	//设置字体大小
	pango_font_description_set_size(font,size*PANGO_SCALE);
	//改变label的字体大小
	gtk_widget_modify_font(GTK_WIDGET(label),font);
	//释放字体指针分配的空间
	pango_font_description_free(font);
}
int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);

	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"vertical layout");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	//创建纵向盒状容器
	GtkWidget *vbox = gtk_vbox_new(TRUE,10);
	//将横向盒装容器放入窗口
	gtk_container_add(GTK_CONTAINER(window),vbox);
	
	//创建label1
	GtkWidget *label1 = gtk_label_new("label1");
	//设置label1字体大小
	set_label_font_size(GTK_LABEL(label1),30);
	//将label1放入纵向盒装容器
	gtk_container_add(GTK_CONTAINER(vbox),label1);
	
	//创建label2
	GtkWidget *label2 = gtk_label_new("label——2");
	//设置label2内容
	gtk_label_set_text(GTK_LABEL(label2),"label2");
	//获得label2内容
	const char *str = gtk_label_get_label(GTK_LABEL(label2));
	g_print("str=%s\n",str);
	//设置lable2字体大小
	set_label_font_size(GTK_LABEL(label2),20);
	//将label2放入横向盒装容器
	gtk_container_add(GTK_CONTAINER(vbox),label2);
	
	//创建label3
	GtkWidget *label3 = gtk_label_new("label3");
	//设置label3字体大小
	set_label_font_size(GTK_LABEL(label3),10);
	//将button3放入横向盒装容器
	gtk_container_add(GTK_CONTAINER(vbox),label3);
	//显示窗口及控件
	gtk_widget_show_all(window);
	
	gtk_main();
	return 0;
}

在这里插入图片描述

表格布局

创建表格布局

GtkWidget *gtk_table_new(guint rows,guint columns,gboolean homogeneous);
rows:行数
columns:列数
homogeneous:容器内的表格大小是否一致(TRUE or FALSE)

添加控件到布局容器中

void gtk_table_attach_defaults(GtkTable *table,GtkWidget *widget,guint left_attach, guint right_attach,guint top_attach,guint bottom_attach);
 table:要容纳控件的容器
 widget:被容纳控件
 后面四个参数是控件摆放的坐标,规则如下:
 A(0,1,0,1)
 B(1,2,0,1)
 C(0,2,1,2)

在这里插入图片描述

例程

#include<gtk/gtk.h>

//button1,button2处理
void callback(GtkButton *button,gpointer data)
{
	//获取按钮的文本内容
	const gchar *text = gtk_button_get_label(button);
	g_printf("%s is clicked\n",text);
}

int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"vertical layout");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	
	//创建表格布局容器
	GtkWidget *table = gtk_table_new(2,2,TRUE);
	//将表格容器放入窗口
	gtk_container_add(GTK_CONTAINER(window),table);
	
	//创建button1
	GtkWidget *button1 = gtk_button_new_with_label("button1");
	//当按钮按下时,触发callback函数
	g_signal_connect(button1,"pressed",G_CALLBACK(callback),NULL);
	//button1的位置
	gtk_table_attach_defaults(GTK_TABLE(table),button1,0,2,0,1);

	//创建button2
	GtkWidget *button2 = gtk_button_new_with_label("button2");
	//当窗口按下时,触发callback函数
	g_signal_connect(button2,"pressed",G_CALLBACK(callback),NULL);
	//button2的位置
	gtk_table_attach_defaults(GTK_TABLE(table),button2,0,2,1,2);

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

在这里插入图片描述

固定布局

创建固定布局容器

GtkWidget *gtk_fixed_new(void);

添加控件到容器

void gtk_fixed_put(GtkFixed *fixed,GtkWidget *widget,gint x,gint y);
 fixed:要容纳控件的容器
 widget:被容纳控件
 x,y:控件摆放位置的起点坐标

例程

#include<gtk/gtk.h>

int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口标题
	gtk_window_set_title(GTK_WINDOW(window),"fix layout");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

	//创建一个固定容器
	GtkWidget *fixed = gtk_fixed_new();
	//将固定容器放入窗口
	gtk_container_add(GTK_CONTAINER(window),fixed);

	//button声明
	GtkWidget *button;
	//for循环创建按钮
	int i;
	for(i = 1;i < 4;i++)
	{
		button = gtk_button_new_with_label("button_%d",i);
		//将按钮组装到固定容器中
		gtk_fixed_put(GTK_FIXED(fixed),button,i*10,i*10);
	}

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

在这里插入图片描述

行编辑

行编辑创建

GtkWidget *gtk_entry_new(void);

显示模式(FALSE为密码模式)

void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible);

获取文本内容

const gchar *gtk_entry_get_text(GtkEntry *entry);

设置行编辑的内容

void gtk_entry_set_text(GtkEntry *entry,const gchar *text);

常用信号

activate:按回车键触发

例程

#include <gtk/gtk.h>

//按回车键,获取行编辑的内容
void enter_callback(GtkWidget *widget,gpointer data)
{
	const gchar *entry_text;
	//获取文本内容
	entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
	g_printf("contents = %s\n",entry_text);
}

int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"entry");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

	//垂直布局,控件均衡摆放
	GtkWidget *vbox = gtk_vbox_new(TRUE,5);
	//将垂直容器放入窗口
	gtk_container_add(GTK_CONTAINER(window),vbox);
	//创建行编辑
	GtkWidget *entry = gtk_entry_new();
	//加入垂直布局
	gtk_container_add(GTK_CONTAINER(vbox),entry);
	//设置行编辑显示最大字符长度
	gtk_entry_set_max_length(GTK_ENTRY(entry),100);
	//设置内容
	gtk_entry_set_text(GTK_ENTRY(entry),"hello GTK");
	//设置密码模式
	gtk_entry_set_visibility(GTK_ENTRY(entry),FALSE);

	//用户在文本输入控件内部按回车键时触发activate信号
	g_signal_connect(entry,"activate",G_CALLBACK(enter_callback),NULL);

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

在这里插入图片描述

按钮控件

带图标按钮的创建

void gtk_button_set_image(GtkButton *button,GtkWidget *image);
 image:通过gtk_image_new_from_file()来创建,参数为图片的路径

设置按钮透明背景色

void gtk_button_set_relief(GtkButton *button,GtkReliefStyle newstyle);
 newstyle: GTK_RELIEF_NONE 透明色

例程

#include <gtk/gtk.h>

void callback(GtkButton *button,gpointer data)
{
	//获取按钮内容
	const char *str = gtk_button_get_lbel(button);
	g_printf("str = %s\",str);
}

int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口标题
	gtk_window_set_title(GTK_WINDOW(window),"Entry");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

	//创建水平布局
	GtkWidget *hbox = gtk_hbox_new(TRUE,10);
	//将横向盒装容器放入窗口
	gtk_container_add(GTK_CONTAINER(window),hbox);

	//普通按钮
	GtkWidget *button1 = gtk_button_new_with_label("normal button");
	//设置按钮内容
	gtk_button_set_label(GTK_BUTTON(button1),"change");
	//链接回调函数
	g_signal_connect(button1,"pressed",G_CALLBACK(callback),NULL);
	//将按钮1放入水平容器
	gtk_container_add(GTK_CONTAINER(hbox),buttton1);

	//图标按钮
	GtkWidget *button2 = gtk_button_new();
	//获取图像
	GtkWidget *image = gtk_image_new_from_file("1.png");
	//按钮设置图像
	gtk_button_set_image(GTK_BUTTON(button2),image);
	//将按钮2放入水平容器中
	gtk_container_add(GTK_CONTAINER(hbox),button2);
	//设置透明度
	gtk_button_set_relief(GTK_BUTTON(button),GTK_RELIEF_NONE);
	//按钮使能设置,默认使能TRUE,非使能FALSE
	//gtk_widget_set_sensitive(button,FALSE);

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

图片控件

图片资源对象的创建

GdkPixbuf *gdk_pixbuf_new_from_file(const gchar *filename,GError **error);
 filename:图片路径
 error:储存错误的指针

设置图片大小

GdkPixbuf *gdk_pixbuf_scale_simple(const GdkPixbuf *src,int dest_width,int dest_height,GdkInterpType interp_type);
 interp_type:是一个枚举类型,标志图片的加载速度和质量,常用GDK_INTERP_BILINEAR

释放资源

void g_object_unref(GtkObject *object);

通过图片资源对象创建图片控件

GtkWidget *gtk_image_new_from_pixbuf(GdkPixbuf *pixbuf);

图片控件重新设置一张图片(pixbuf)

void gtk_image_set_from_pixbuf(GtkImage *image,GdkPixbuf *pixbuf);

清除控件里的图像数据

void gtk_image_clear(GtkImage *image);

例程

#include <gtk/gtk.h>

//button1,button2处理
void callback(GtkButton *button,gpointer data)
{
	char *str = (char *)data;
	char *path_buf[] = {"./image/1.bmg","./image/2.bmp","./image/3.bmp"};
	static int i = 0;
	if(strcmp(str,"up") == 0)
	{
		g_printf("上一张图片\n");
		i--;
		if(i < 0)
			i = 2;
		load_image_file(iamge,path_buf[i],571,342);
	}
	else if(strcmp(str,"down") == 0)
	{
		g_printf("下一张图片\n");
		i++;
		if(i > 2)
			i = 0;
		load_image_file(image,path_buf[i],571,342);
	}
	else
	{}
}
//创建图片资源
GdkPixbuf *creat_pixbuf(char * file_path,int width,int height)
{
	//创建图片资源
	GdkPixbuf *src_pixbuf = gdk_pixbuf_new_from_file(file_path,NULL);
	//设置图片大小
	GdkPixbuf *dest_pixbuf = gdk_pixbuf_scale_simple(src_pix,width,height,GDK_INTERP_BILINEAR);
	//释放图片资源
	g_object_unref((GtkObject *)src_pix);
	return dest_pixbuf;
}
//加载图片资源
void load_image_file(GtkWidget *image,char *file_path,int width,int height)
{
	//通过自建函数创建新的图片资源
	GdkPixbuf *dest_pixbuf = creat_pixbuf(file_path,width,height);
	//清除图片控件中的图像数据
	gtk_image_clear(GTK_IMAGE(image));
	//刷新图片控件
	gtk_image_set_from_pixbuf(GTK_IMAGE(image),dest_pixbuf);
	//释放新的图片资源
	g_object_unref((GtkObject *)dest_pixbuf);
}


int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);

	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"图库");
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,800,480);
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//固定窗口大小
	gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
	//destroy和gtk_main_quit连接
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	
	//创建表格容器
	GtkWidget *table = gtk_table_new(7,7,TRUE);
 	//将表格容器放入窗口
 	gtk_container_add(GTK_CONTAINER(window),table);

	//创建button1
	GtkWidget *button1 = gtk_button_new_with_label("button1");
	//图像控件
	GtkWidget *button1_img = gtk_image_new_from_file("./image/up.jpg");
	//将图像绑定到按钮
	gtk_button_set_image(GTK_BUTTON(button1),button1_image);
	//当按钮按下时,触发callback函数
	g_signal_connect(button1,"pressed",G_CALLBACK(callback),"up");
	//button1的位置
	gtk_table_attach_defaults(GTK_TABLE(table),button1,1,2,6,7);

	//创建button2
	GtkWidget *button2 = gtk_button_new_with_label("button2");
	//图像控件
	GtkWidget *button2_img = gtk_image_new_from_file("./image/down.jpg");
	//将图像绑定到按钮
	gtk_button_set_image(GTK_BUTTON(button2),button2_image);
	//当窗口按下时,触发callback函数
	g_signal_connect(button2,"pressed",G_CALLBACK(callback),"down");
	//button2的位置
	gtk_table_attach_defaults(GTK_TABLE(table),button2,5,6,6,7);
	
	//通过自建函数创建图片资源
	GdkPixbuf *dest_pixbuf = creat_pixbuf("./image/1.jpg",571,342);
	//创建图片控件
	GtkWidget *image = gtk_image_new_from_pixbuf(dest_pixbuf);
	//释放图片资源
	g_object_unref((GtkObject *)dest_pixbuf);
	//将图片放入在表格容器
	gtk_table_attach_defaults(GTK_TABLE(table),image,1,6,1,6);
	
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}

进度条

创建进度条

GtkWidget *gtk_progress_bar_new(void);

设置进度条显示的百分比

void gtk_progress_bar_set_fraction(GtkProgressBar *pbar,gdouble fraction);
 fraction: 0.01.0

设置滑槽上的文本显示

void gtk_progress_bar_set_text(GtkProgressBar *pbar,gchar *text);

设置进度条的移动方向

void gtk_progress_bar_set_orientation(GtkProgressBar *pbar,GtkProgressOrientation orientation);
 GTK_PROGRESS_LEFT_TORIGHT:从左到右
 GTK_PROGRESS_RIGHT_TO_LEFT:从右到左
 GTK_PROGRESS_BOTTOM_TO_TOP:从下到上
 GTK_PROGRESS_TOP_TO_BOTTOM:从上到下

例程

#include<gtk/gtk.h>

void progress_set_orientation(GtkWidget *widget,gpointer data)
{
  switch(gtk_progress_bar_get_orientation(GTK_PROGRESS_BAR(data)));
  {
    case GTK_PROGRESS_LEFT_TO_RIGHT:
      gtk_progress_bar_set_orientatio(GTK_PROGRESS_BAR(data),GTK_PROGRESS_RIGHT_TO_LEFT);
    break;
    case GTK_PROGRESS_RIGHT_TO_LEFT:
      gtk_progress_bar_set_orientatio(GTK_PROGRESS_BAR(data),GTK_PROGRESS_LEFT_TO_RIGHT);  
    break;
    default:
    break;
  }
}

void progress_add(GtkWidget *widget,gpointer data)
{
  //获取当前进度值
  gdouble new_val  = gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(data)) + 0.05;
  //越界处理
  if(new_val > 1.0)
  	new_val = 0.0;
  //重新设置进度值
  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data),new_val);
}

int main(int argc,char *argv[])
{
 gtk_init(&argc,&argv);
 
 //创建顶层窗口
 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 //设置窗口居中
 gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
 //设置窗口大小
 gtk_widget_set_size_request(window,300,200);
 //设置窗口边框的宽度
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //设置窗口的标题
 gtk_window_set_title(GTK_WINDOW(window),"进度条");
 //设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
 g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
 
 //创建垂直布局容器
 GtkWidget *vbox = gtk_vbox_new(FALSE,5);
 //将垂直布局放入窗口
 gtk_container_add(GTK_CONTAINER(window),vbox);

 //创建进度条
 GtkWidget *progress = gtk_progress_bar_new();
 //加入垂直容器
 gtk_container_add(GTK_CONTANER(vbox),progress,0.5);
 //设置进度条显示50%
 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress),0.5);
 //设置在滑槽上显示的文本
 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),"播放进度");
 
 //创建按钮切换移动方向
 GtkWidget *button1 =gtk_button_new_with_label("left or right");
 //按钮链接回调函数
 g_signal_connect(button1,"clicked",G_CALLBACK(progress_set_orientation),progress);
 //加入垂直布局
 gtk_container_add(GTK_CONTAINER(vbox),button1);

 //增加进度条进度按钮
 GtkWidget *button2 = gtk_button_new_with_label("add");
 //按钮链接回调函数
 g_signal_connect(button2,"clicked",G_CALLBACK(progress_add),progress);
 //加入垂直布局
 gtk_container_add(GTK_CONTAINER(vbox),button2);

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

滚动窗口

创建滚动窗口

GtkWidget *gtk_scrolled_window_new(GtkAdjustment *hadjustment,GtkAdjustment *vadjustment);
 hadjustment:水平方向的调整对象
 vadjustment:垂直方向的调整对象
 一般情况下都取NULL

滚动窗口添加控件

void gtk_scrolled_window_add_with_viewport(GtkScrolledWindow *scrolled_window,GtkWidget *child);

设置滚动条出现的方式(水平或垂直)

void gtk_scrolled_window_set_policy(GtkScrolledWindow *scrolled_window,GtkPolicyType hscrollbar policy,GtkPolicyType vscrollbar policy);
 GTK_POLICY_AUTOMATIC:滚动条根据需要自动出现
 GTK_POLICY_ALWAYS:滚动条总是出现
 GTK_POLICY_NEVER:不需要滚动条

例程

#include <gtk/gtk.h>

int main(int argc,char *argv[])
{
 gtk_init(&argc,&argv);
 
 //创建顶层窗口
 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 //设置窗口居中
 gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
 //设置窗口大小
 gtk_widget_set_size_request(window,300,200);
 //设置窗口边框的宽度
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //设置窗口的标题
 gtk_window_set_title(GTK_WINDOW(window),"滚动窗口");
 //设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
 g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

 //创建滚动窗口
 GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL,NULL);
 //设置滚动窗口边框的宽度
 gtk_container_set_border_width(GTK_CONTAINER(scrolled_window),10);
 //将滚动窗口放入窗口中
 gtk_container_add(GTK_CONTAINER(window),scrolled_window);
 //设置水平和垂直滚动条出现的条件
 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);

 //创建标签
 GtkWidget *label = gtk_label_new("aaaaaaaaaaaaaaaaaaaaaaaaa"\
 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"\
 "	cccccccccccccccccccccccccccccccccccccccccccccccccccc"\
 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"\
 "ddddddddddddddddddddddddddddddddddd"\
 "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 //label自动换行
 gtk_label_set_line_wrap(GTK_LABEL(label),TRUE);
 //将标签组装到滚动窗口
 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),label);
 
 gtk_widget_show_all(window);
 gtk_main();
 return 0;
}

分栏列表

创建列表

GtkWidget *gtk_clist_new_with_titles(gint columns,gchar *titles[]);
 columns:列数
 titles:标题,指针数目应该与列数相等

设置某一列的宽度

void gtk_clist_set_column_width(GtkClist *clist,gint column,gint width);

设置某列内容显示的对齐方式

void gtk_clist_set_column_justification(GtkCList *clist,gint column,GtkJustification justification);
 GTK_JUSTIFY_LEFT:左对齐
 GTK_JUSTIFY_RIGHT:右对齐
 GTK_JUSTIFY_CENTER:居中对齐
 GTK_JUSTIFY_FILL:填充

向列表中添加行

gint gtk_clist_append(GtkCList *clist,gchar *text[]);

删除列表中所有的行

void gtk_clist_clear(GtkCList *clist);

获取某一行某一列的内容

gint gtk_clist_get_text(GtkCList *clist,gint row,gint column,gchar **text);

常用信号

select-row :选中某一行触发

例程

#include <gtk/gtk.h>

void selection_content(GtkWidget *clist,gint row,gint column,GdkEventButton *event, gpointer data)//row,column会自动相应取值
{
 //更新列表,高亮显示
 gtk_widget_queue_draw(clist);
 gchar *text;
 gtk_clist_get_text(GTK_CLIST(clist),row,column,&text);
 g_print("第 %d 行,第 %d 列的内容为 %s\n",row,column,text");
}

void button_add_clicked(GtkWidget *widget,gpointer data)
{
 char *a[2] = {"hello","123"};
 gtk_clist_append(GTK_CLIST(data),a);
 char *b[2] = {"world","456"};
 gtk_clist_append(GTK_CLIST(data),b);
}

void button_clear_cliked(GtkWidge *widget,gpointer data)
{
 gtk_clis_clear(GTK_CLIST(data));
}
int main(int argc,char *argv[])
{
 gtk_init(&argc,&argv);
 
 //创建顶层窗口
 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 //设置窗口居中
 gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
 //设置窗口大小
 gtk_widget_set_size_request(window,300,200);
 //设置窗口边框的宽度
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //设置窗口的标题
 gtk_window_set_title(GTK_WINDOW(window),"滚动窗口");
 //设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
 g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
 
 //创建表格布局
 GtkWidget *table = gtk_table_new(5,2,TRUE);
 //将表格布局放入窗口
 gtk_container_add(GTK_CONTAINER(window),table);

 //创建滚动窗口
 GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL,NULL);
 //将滚动窗口放入表格布局
 gtk_table_attach_defaults(GTK_TABLE(table),scrolled_window,0,2,0,4);
 //滚动条根据需要显示
 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
 
 //命名字符串数组
 gchar *titles[2] = {"Ingredients","Amount"};
 //创建GtkCList
 GtkWidget *clist = gtk_clist_new_with_title(2,titles);
 //将GtkCList控件添加到滚动窗口控件中
 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),clist);
 //设置某列对齐方式
 gtk_clist_set_column_justification(GTK_CLIST(clist),1,GTK_JUSTIFY_CENTER);
 //设置某列宽度
 gtk_clist_set_column_width(GTK_CLIST(clist),0,150);
 //选择某一行时触发回调函数
 g_signal_connect(clist,"select-row",G_CALLBACK(selection_content),NULL);

 //创建按钮
 GtkWidget *button_add = gtk_button_new_with_label("add list");
 GtkWidget *button_clear = gtk_button_new_with_label("clear list");
 //将按钮放入容器布局中
 gtk_table_attach_defaults(GTK_TABLE(table),button_add,0,1,4,5);
 gtk_table_attach_defaults(GTK_TABLE(table),button_clear,1,2,4,5);
 //链接回调函数
 g_signal_connect(button_add,"clicked",G_CALLBCK(button_add_clicked),(gpointer)clist);
 g_signal_connect(button_clear,"clicked",G_CALLBACK(button_clear_clicked),(gpointer)clist);
 //设置分栏列表风格
 gtk_clist_set_row_style(GTK_CLIST(clist),2,NULL);
 
 gtk_widget_show_all(window);
 gtk_main();
 return 0;
}

定时器

例程

#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>

guint timer;

void set_widget_font_size(GtkWidget *widget,int size,int is_button)
{
 GtkWidget *labelChild;
 PangoFontDescription *font;
 gint fontSize = size;

 //"San"字体名
 font = pango_font_description_from_string("Sans");
 //设置字体大小
 pango_font_description_set_size(font,fontSize *PANGO_SCALE);

 if(is_button)
 {
  //取出GtkButton中的label
  labelChild = gtk_bin_get_child(GTK_BIN(widgt));
 }
 else
 {
  labelchild = widget;
 }
 
 //设置label的字体
 gtk_widget_modify_font(GTK_WIDGET(labelchild),font);
 pango_font_description_free(font);
}

gboolean deal_time(GtkWidget *label)
{
 char buf[5] = "";
 static int num = 10;
 num--;
 sprintf(buf,"%d",num);
 gtk_label_set_text(GTK_LABEL(label),buf);

 if(num == 0)
 {
  num = 11;
  //移除定时器
  //g_source_remove(timer);
 }
 return TRUE;
}
int main(int argc,char *argv[])
{
 gtk_init(&argc,&argv);
 
 //创建顶层窗口
 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 //设置窗口居中
 gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
 //设置窗口大小
 gtk_widget_set_size_request(window,300,200);
 //设置窗口边框的宽度
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //设置窗口的标题
 gtk_window_set_title(GTK_WINDOW(window),"定时器");
 //设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
 gtk_container_set_border_width(GTK_CONTAINER(window),10);
 //当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
 g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
 
 //创建label
 GtkWidget *label = gtk_label_new("10");
 //设置label的字体大小
 set_widget_font_size(label,230,FALSE);
 //将label装入窗口中
 gtk_container_add(GTK_CONTAINER(window),label);

 //创建定时器
 timer = g_timeout_add(500,(GSourceFunc)deal_time,(gpointer)label);

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

事件处理

介绍

GTK+提供的工具库与其他应用程序都是基于事件触发机制来管理,所有的应用程序都是基于事件驱动。如果没有事件发生,应用程序将处于等待状态,不会执行任何操作,一旦事件发生,将根据不同的事件做出相应的处理。
在GTK+中当一个事件发生时,程序就会通过发送一个信号来通知应用程序执行相关的操作,即调用与这一信号进行连接的回调函数,来完成一次由事件所触发的行动。

事件捕获

设置控件捕获相应的事件

void gtk_widget_add_event(GtkWidget *widget,gint events)
 events:事件类型,它是GdkEventMask的枚举类型
 GDK_BUTTON_PRESS_MASK:鼠标点击
 GDK_BUTTON_RELEASE_MASK:鼠标释放
 GDK_BUTTON_MOTION_MASK:鼠标移动
 GDK_KEY_PRESS_MASK:键盘按下
 GDK_ENTER_NOTIFY_MASK:进入控件区域
 …… ……

鼠标事件

主窗口默认不接收鼠标事件,需要手动添加

触发鼠标点击事件的信号:button-press-event
触发鼠标释放事件的信号:button-release-event
回调函数的定义

gboolean callback(GtkWidget *widget,GdkEventButton *event,gpointer data)
 event->x,event-y:得到点击坐标值
 event->button:鼠标哪个键按下
 event->type:是否双击

触发鼠标移动事件的信号:motion-notify-event
回调函数的定义

gboolean callback(GtkWidget *widget,GdkEventMotion *event,gpointer data)
 event->x,event->y:得到移动的坐标值

注意:
可以在GtkWidget里找到相应的事件信号

例程

#include <gtk/gtk.h>

gboolean mask_button_callback(GtkWidget *widget,GdkEventButton *event,gpointer data)
{
	switch(event->button)
	{
		case 1:
			g_printf("左键按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		break;
		case 3:
			g_printf("右键按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		break;
	}
	
	switch(event->type)
	{
		case GDK_BUTTON_PRESS
			g_printf("单击按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		break;
		case GDK_2BUTTON_PRESS
			g_printf("双击按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		//现象:双击时打印两次单击按下
		break;
	}
	return TRUE;
}

gboolean mask_motion_callback(GtkWidget *widget,GdkEventMotion *event,gpointer data)
{
	g_printf("鼠标移了:x=%d,y=%d\n",(int)event->x,(int)event->y);
}
int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"entry");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

	//主窗口添加鼠标单击事件|鼠标移动事件
	gtk_widget_add_event(window,GTK_BUTTON_PRESS_MASK | GTK_BUTTON_MOTION_MASK);
	
	//链接鼠标点击事件
	g_signal_connect(window,"button-press-event",G_CALLBACK(mask_button_callback),NULL);
	
	//链接鼠标移动事件
	g_signal_connect(window,"motion-notify-event",G_CALLBACK(mask_motion_callback),NULL);
	
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}

键盘事件

主窗口默认就能接收键盘事件,其中的键盘定义在/usr/include/gtk-2.0/gdk/gdkkeysyms-compat.h 文件中.

触发键盘按下事件的信号:key-press-event
触发键盘释放事件的信号:key-release-event

回调函数定义:

gboolean callback(GtkWidget *widget,GdkEventKey *event,gpointer data)
 event->keyval:获取按下(释放)的键盘键值

例程

#include <gtk/gtk.h>//头文件
#include <gdk/gdkkeysyms.h>//键盘事件

gboolean key_callback(GtkWidget *widget,GdkEventKey *event,gpointer data)
{
	switch(event->keyval)
	{
		case GDK_Up:
			g_printf("上键\n");
		break;
		case GDK_Down:
			g_printf("下键\n");
		break;
		case GDK_q:
			g_print("小写字母q\n");
		break;
		case GDK_R:
			g_printf("大写字母R\n");
		break;
	}
	return TRUE;
}

int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"entry");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

	g_signal_connect(window,"key-press-event",G_CALLBACK(key_callback),NULL);
	
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}

事件盒子

有些控件(GdkLabel)不响应GDK事件,GTK+通过事件盒子给控件提供一个GDK窗口来捕获事件。
操作步骤:
1,创建事件盒子
2,给事件盒子中添加事件(鼠标事件、键盘事件)
3,将其他控件放入事件盒子中(Label)

事件盒子的创建

GtkWidget *gtk_event_box_new(void)

添加事件到事件盒子中

gtk_widget_set_events(box,GDK_BUTTON_PRESS_MASK);

添加控件到事件盒子中

void gtk_container_add(GtkContainer *container,GtkWidget *widget)

例程

#include <gtk/gtk.h>//头文件
#include <gdk/gdkkeysyms.h>//键盘事件

gboolean mask_button_callback(GtkWidget *widget,GdkEventButton *event,gpointer data)
{
	switch(event->button)
	{
		case 1:
			g_printf("左键按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		break;
		case 3:
			g_printf("右键按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		break;
	}
	
	switch(event->type)
	{
		case GDK_BUTTON_PRESS
			g_printf("单击按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		break;
		case GDK_2BUTTON_PRESS
			g_printf("双击按下,x=%d,y=%d\n",(int)event->x,(int)event->y);
		//现象:双击时打印两次单击按下
		break;
	}
	g_printf("label=%s\n",(gchar *)data);
	return TRUE;
}

int main(int argc,char *argv[])
{
	gtk_init(&argc,&argv);
	
	//创建顶层窗口
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	//设置窗口居中
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	//设置窗口大小
	gtk_widget_set_size_request(window,300,200);
	//设置窗口的标题
	gtk_window_set_title(GTK_WINDOW(window),"entry");
	//设置窗口边框的宽度(窗口里的控件与窗口边框间隔为10)
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
	//当窗口关闭时,窗口会触发destroy信号,自动调用gtk_main_quit()结束程序运行
	g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
	
	//创建事件盒子
	GtkWidget *eventbox = gtk_event_box_new();
	//将事件盒子添加到主窗口中
	gtk_container_add(GTK_CONTAINER(window),eventbox);
	//将鼠标事件添加到事件盒子中
	gtk_widgetset_evens(eventbox,GDK_BUTTON_PRESS_MASK);
	//创建Label控件
	GtkWidget *label = gtk_label_new("label单击")//将Label控件添加到事件盒子中
	gtk_cotainer_add(GTK_CONTAINER(eventbox),labe);
	//链接信号到鼠标回调函数,注意此时不是window而是eventbox
	g_signal_connect(eventbox,"button-press-event",G_CALLBACK(mask_button_callback),label);
	
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}

glade使用

glade是GTK+的界面辅助设计工具,可以通过拖放控件的方式快速设计出用户界面,优势在于设计的同时能直观的看到界面的控件,并且可以随时调整界面上的设计。

开发板的库版本为gtk2.12之前的版本(gtk1.0),只支持libglade模式,linux环境的版本只能保存GtkBuilder格式的glade,但是可以运行libglade的代码,windows的glade安装包两种格式都支持,所以使用windows的glade设计界面,然后在linux编译运行代码

windows版本的glade(glade3-3.6.7-with-GTK+.exe)

网址:http://download.csdn.net/detail/u013293310/6829273
官网:https://glade.gnome.org/

linux环境的glade

sudo apt-get install glade libglade2-dev

glade需要的头文件

include <glade/glade.h>

makefile修改

CC = gcc
MAINC = glade.c//修改成使用的glade文件名
EXEC = demo

CFLASS = `pkg-config --cflags --libs gtk+-2.0 gmodule-export-2.0 libglade-2.0`

main:
	$(CC) $(MAINC) -o $(EXEC) $(CFLASS)
clean:
	rm $(EXEC) -rf

例程

#include <gtk/gtk.h>//头文件
#include <glade/glade.h>

void button_press(GtkButton *button,gpointer data)
{
	printf("按键已按下\n");
}

int main(int argc,char *argv[])
{
	GtkWidget *window = NULL;
	gtk_init(&argc,&argv);

	//创建xml文件指针 修改为当前文件夹中的glade文件
	GladeXML *gxml = glade_xml_new("./myGlade.glade",NULL,NULL);
	//获得主窗口 修改为glade中主窗口名
	window = glade_xml_get_widget(gxml,"window");

	//获取按键 修改为glade中按键名
	GtkWidget *backbutton = glade_xml_get_widget(gxml,"back_button");
	//信号连接
	g_signal_connect(backbutton,"clicked",G_CALLBACK(button_press),NULL);
	
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值