GTK+浅谈之六自由布局并移动控件位置

一、简介

        Gtk+2.0使用自由布局控件,类似Qt中的move函数,按几何坐标方式向其中添加排列控件。并通过键盘按键事件动态移动图像控件的位置。

二、详解

(1)代码:gtkfixed.c
//创建使用自由布局控件,接收和控制键盘的输入,动态更改图像控件的显示内容
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

//定义枚举类型:四个元素分别代表左,上,右,下
enum _FORWARD { LEFT, UP, RIGHT, DOWN };  
//定义方向类型 Forward为枚举类型变量
typedef enum _FORWARD Forward;

static gchar *image_file[4] = {"1.png","2.png","3.png","4.png"}; //指针数组 放图片
static GtkWidget *fixed;
static GtkWidget *image;
gint i = 75;//显示的横坐标
gint j = 75;//显示的纵坐标
Forward forward = UP; //定义方向 

//按键后所用的函数 显示按键后的位置
/*设置控件的大小( 宽和高 ):
void gtk_widget_set_size_request( GtkWidget *widget,gint width,gint height );
widget:需要设置的控件
width:宽度
height:高度
*/
/*固定布局容器添加控件:
*void gtk_fixed_put(GtkFixed *fixed,GtkWidget *widget,gint x,gint y );
*fixed:容纳控件的容器
*widget:要添加的控件
*x, y:控件摆放位置的起点坐标
*/
/*移动固定布局里控件的位置:
*void gtk_fixed_move(GtkFixed *fixed,GtkWidget *widget,gint x,gint y);
*fixed:固定布局容器
*widget:需要移动的控件
*x, y: 移动的位置
*/
static void move (Forward fw)
{
	switch(fw) {
	//按钮"上"的功能
	case UP :
		j = j - 5 ; //纵坐标减少5
		if ( j < 0 ) j = 175 ; //如果纵坐标小于0 则图片在顶端显示
		gtk_image_set_from_file(GTK_IMAGE(image),image_file[0]);//放入图片
		gtk_fixed_move(GTK_FIXED(fixed),image,i,j);//移动后图片显示及位置
		break;
	//按钮"下"的功能
	case DOWN :
		j = j + 5 ;//纵坐标加5
		if ( j > 200 ) j = 0;//如果纵坐标大于200 则图片在底端显示
		gtk_image_set_from_file(GTK_IMAGE(image),image_file[2]);
		gtk_fixed_move(GTK_FIXED(fixed),image,i,j);
		break;
	//按钮"左"的功能
	case LEFT :
		i = i - 5 ;//横坐标减少5
		if ( i < 0 ) i = 175 ;//如果横坐标小于0 则图片在最右端显示
		gtk_image_set_from_file(GTK_IMAGE(image),image_file[3]);
		gtk_fixed_move(GTK_FIXED(fixed),image,i,j);
		break;
	//按钮"右"的功能
	case RIGHT :
		i = i + 5 ;//横坐标加5
		if ( i > 200 )  i = 0 ;//如果横坐标大于200 则图片在最左端显示
		gtk_image_set_from_file(GTK_IMAGE(image),image_file[1]);
		gtk_fixed_move(GTK_FIXED(fixed),image,i,j);
		break;
	}
}

//按键函数:按键发生后,调用函数
static void key_press (GtkWidget *widget,GdkEventKey *event,gpointer data)
{
	switch(event->keyval) {
	//按键"上"被按下
	case GDK_Up :
		forward = UP; //令枚举类型变量为UP
		move(forward);//调用函数实现功能
		break;
	//按键"下"被按下
	case GDK_Down :
		forward = DOWN;//令枚举类型变量为DOWN
		move(forward);//调用函数实现功能
		break;
	//按键"左"被按下
	case GDK_Left :
		forward = LEFT;//令枚举类型变量为LEFT
		move(forward);//调用函数实现功能
		break;
	//按键"右"被按下
	case GDK_Right :
		forward = RIGHT;//令枚举类型变量为RIGHT
		move(forward);//调用函数实现功能
		break;
	}
}
static gint configure_event(GtkWidget *widget, gpointer data)
{
g_printf("configure_event\n");
return TRUE;
}

//主函数
int main (int argc, char *argv[])
{
	GtkWidget *window; 
	GtkWidget *vbox;
	GtkWidget *bbox;
	GtkWidget *sep;
	GtkWidget *frame;
	GtkWidget *button;
	
	gtk_init(&argc,&argv);
	//设定主窗口
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window),"图像的动态移动");
	gtk_container_set_border_width(GTK_CONTAINER(window),10);
      gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
      gtk_window_set_resizable (GTK_WINDOW (window), FALSE);    //隐藏最大化按钮并且无法改变窗口大小
	g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

	//键盘按键事件	
	g_signal_connect(G_OBJECT(window),"key_press_event",G_CALLBACK(key_press),NULL);
      //g_signal_connect (G_OBJECT(window),"configure_event",G_CALLBACK(configure_event), NULL);
	
	//创建一个盒子后放入窗口中	
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(window),vbox);
	//创建一个无标签框架	
	frame = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
	
	//创建一个固定窗口并设置窗口大小,返回固定布局容器指针
	fixed = gtk_fixed_new();
	//
	gtk_fixed_set_has_window(GTK_FIXED(fixed),TRUE);
	//设置固定窗口大小
	gtk_widget_set_size_request(fixed,200,200);
	//设置图片及显示位置	
	image = gtk_image_new_from_file(image_file[0]);
	gtk_fixed_put(GTK_FIXED(fixed),image,i,j);
	//加入框架中
	gtk_container_add(GTK_CONTAINER(frame),fixed);
	//框架加入盒子中
	gtk_box_pack_start(GTK_BOX(vbox),frame,TRUE,TRUE,5);
	
	//创建一个横向分割器放入盒子中
	sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox),sep,FALSE,FALSE,5);
	
	//创建一个横向按钮盒并设置外观放入vbox盒子中 	
	bbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox),GTK_BUTTONBOX_END);
	gtk_box_pack_start(GTK_BOX(vbox),bbox,FALSE,FALSE,5);
	
	//设置退出按键	
	button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
	g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(gtk_main_quit),NULL);
	gtk_box_pack_end(GTK_BOX(vbox),button,FALSE,FALSE,5);
	
	gtk_widget_show_all(window);
	gtk_main();
	return FALSE;
}
(2)编译及运行

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

三、总结

(1)暂时还不能实现控件随整个窗口的改变而动态改变,因此先隐藏最大化按钮,以后有时间进一步研究。
(2)若有建议,请留言,在此先感谢!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值