博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GTK--布局管理
阅读量:6464 次
发布时间:2019-06-23

本文共 9924 字,大约阅读时间需要 33 分钟。

版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/46432975

这一小结,将要学习将构建布局在窗口和对话框中.为了方便的管理我们的构件,在GTK+中,通常使用不可见的构件称作layout containers.

这一小节将要讨论GtkAlignment,GtkFixed,GtkVBox,GtkTable.

(一):GtkFixed

容器构建GtkFixed用于布置子构件在一个固定的位置和设定固定的大小.这种构件并不属于自动的布局关系器.实质上,在大多数应用程序中,并不多使用GtkFixed;
而在只用于一些比较特殊的场合,例如:游戏,含有绘图功能的专用软件,那些需要移动和调整大小的软件(如电子表格中的图标)以及那些小型的教育用途软件.

下面我们看一个例子:

#include 
int main(int argc,char *argv[]){ GtkWidget *window; GtkWidget *fixed; GtkWidget *button1; GtkWidget *button2; GtkWidget *button3; gtk_init(&argc,&argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window),"GtkFixed"); gtk_window_set_default_size(GTK_WINDOW(window),290,200); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window),fixed); button1 = gtk_button_new_with_label("Button"); gtk_fixed_put(GTK_FIXED(fixed),button1,150,50); gtk_widget_set_size_request(button1,80,35); button2 = gtk_button_new_with_label("Button"); gtk_fixed_put(GTK_FIXED(fixed),button2,15,15); gtk_widget_set_size_request(button2,80,35); button3 = gtk_button_new_with_label("Button"); gtk_fixed_put(GTK_FIXED(fixed),button3,100,100); gtk_widget_set_size_request(button3,80,35); g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL); gtk_widget_show_all(window); gtk_main(); return 0;}

下面是运行的结果:

在上面的例子中,我们使用代码生成了三个按钮,这三个按钮布局在固定的位置上.当窗口的大小改变的时候,按钮将会固定保持他们的大小和固定的坐标.

使用函数gtk_fixed_new()就能够生成一个GtkFixed的容器构件.如果我们想要想容器中添加组件,使用函数:

gtk_fixed_put(),例如gtk_fixed_put(GTK_FIXED(fixed),button1,150,50);

button1的坐标为x=150,y=50

(二):GtkVBox

GtkVBox是一种用于垂直布局的容器构件,他把放置在他中的子构件放置在一个单独的列中.类似的是 GtkHBox是放在一个单独的行中,是一种水平布局.

下面我们看一个例子:

#include 
int main(int argc,char *argv[]){ GtkWidget *window; GtkWidget *vbox; GtkWidget *settings; GtkWidget *accounts; GtkWidget *loans; GtkWidget *cash; GtkWidget *debts; gtk_init(&argc,&argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),230,250); gtk_window_set_title(GTK_WINDOW(window),"GtkVBox"); gtk_container_set_border_width(GTK_CONTAINER(window),5); vbox = gtk_vbox_new(TRUE,1); gtk_container_add(GTK_CONTAINER(window),vbox); settings = gtk_button_new_with_label("Settings"); accounts = gtk_button_new_with_label("Accounts"); loans = gtk_button_new_with_label("Loans"); cash = gtk_button_new_with_label("Cash"); debts = gtk_button_new_with_label("Debts"); gtk_box_pack_start(GTK_BOX(vbox),settings,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),accounts,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),loans,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),cash,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),debts,TRUE,TRUE,0); g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0;}

下面是程序的运行结果:

效果很明显,垂直排版,所以我们在排版菜单选项的时候,就是使用这个工具的.

在上面这个例子中,如果改变窗口大小的时候,按钮的大小也会发生改变的.

使用函数gtk_vbox_new()可以生成GtkBox构件.在本例子中:

vbox = gtk_vbox_new(TRUE,1);

第一个参数设置为TRUE,表示所有的按钮大小都是一样的,并且按钮之间的距离设置为”1”像素.

至于下面这个函数

gtk_box_pack_start(GTK_BOX(vbox),settings,TRUE,TRUE,0);
该函数将”settings”构件布局在vbox 容器中.其中该函数的前两个参数分别是存放构件的容器和搜要放置的构件.后面的三个参数分别是expand,fill和padding,如果fill对应的参数如果设置为FALSE的话,按钮就不会充满整个vbox构件.如果之前在gtk_vbox_new(TRUE,1);中已经设置按钮都是等宽高的话,expand对应的参数是完全没有效果的.(在这里尽量这两个参数都设置成TRUE).

(三):GtkTable容器

GTkTabel容器,顾名思义,该容器类似于一个表格,既可以按照行来布局,也可以按照列来布局.

下面是我们的一个例子.

#include 
int main(int argc,char *argv[]){ GtkWidget *window; GtkWidget *table; GtkWidget *button; char *values[16] = {
"7","8","9","/","4","5","6","*","1","2", "3","-","0",".","=","+"}; gtk_init(&argc,&argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),250,180); gtk_window_set_title(GTK_WINDOW(window),"GtkTable"); gtk_container_set_border_width(GTK_CONTAINER(window),5); table = gtk_table_new(4,4,TRUE); gtk_table_set_row_spacings(GTK_TABLE(table),2); gtk_table_set_col_spacings(GTK_TABLE(table),2); int i = 0; int j = 0; int pos = 0; for(i = 0;i < 4;i++){ for(j = 0;j < 4;j++){ button = gtk_button_new_with_label(values[pos]); gtk_table_attach_defaults(GTK_TABLE(table),button,j,j+1,i,i+1); pos++; } } gtk_container_add(GTK_CONTAINER(window),table); g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0;}

下面是运行之后的效果:

通过上面运行的效果,我们看到我们做的是一个计算机的布局.

table = gtk_table_new(4,4,TRUE);

这样就生成了一个GtkTabel布局构件,并设置为4行4列.

gtk_table_set_row_spacings(GTK_TABLE(table),2);gtk_table_set_col_spacings(GTK_TABLE(table),2);

这两个函数的目的是设置每行与每列的距离.

for(i = 0;i < 4;i++){        for(j = 0;j < 4;j++){            button = gtk_button_new_with_label(values[pos]);            gtk_table_attach_defaults(GTK_TABLE(table),button,j,j+1,i,i+1);            pos++;          }    }

该代码将会生成16个按钮并把他们布局 在GtkTable容器构件中.

(四):GtkAlignment

GtkAlignment容器构件控制了她的子构件的对齐方式和大小.

下面我们看一个例子.

#include 
int main(int argc,char *argv[]){ GtkWidget *window; GtkWidget *ok; GtkWidget *close; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *halign; GtkWidget *valign; gtk_init(&argc,&argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),350,200); gtk_window_set_title(GTK_WINDOW(window),"GtkAlignment"); gtk_container_set_border_width(GTK_CONTAINER(window),10); vbox = gtk_vbox_new(FALSE,5); valign = gtk_alignment_new(0,1,0,0); gtk_container_add(GTK_CONTAINER(vbox),valign); gtk_container_add(GTK_CONTAINER(window),vbox); hbox = gtk_hbox_new(TRUE,3); ok = gtk_button_new_with_label("OK"); gtk_widget_set_size_request(ok,70,30); gtk_container_add(GTK_CONTAINER(hbox),ok); close = gtk_button_new_with_label("Close"); gtk_container_add(GTK_CONTAINER(hbox),close); halign = gtk_alignment_new(1,0,0,0); gtk_container_add(GTK_CONTAINER(halign),hbox); gtk_box_pack_start(GTK_BOX(vbox),halign,FALSE,FALSE,0); g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0;}

下面是程序运行的结果:

在这个例子中,将两个按钮布局到一个窗口的右下角.为了实现这个效果,我们使用了一个水平盒子构建horizontal box,一个竖直盒子构建vertical box和两个对齐容器构件alignment containers.

valign = gtk_alignment_new(0,1,0,0);

这样生成一个对齐容器构件.

gtk_conatiner_add(GTK_CONTAINER(vbox),valign);

将对齐容器构件布局在水平盒子中.

hbox = gtk_hbox_new(TRUE,3);        ok = gtk_button_new_with_label("OK");    gtk_widget_set_size_request(ok,70,30);    gtk_container_add(GTK_CONTAINER(hbox),ok);    close = gtk_button_new_with_label("Close");    gtk_container_add(GTK_CONTAINER(hbox),close);

上面代码首先生成一个水平盒子,并将两个按钮布局在里面.

halign = gtk_alignment_new(1,0,0,0);    gtk_container_add(GTK_CONTAINER(halign),hbox);    gtk_box_pack_start(GTK_BOX(vbox),halign,FALSE,FALSE,0);

上述代码生成一个对齐容器构件,然后将其子控件布局在右边,我们把水平盒子添加到对齐容器构件中,然后又把对齐容器构件添加到竖直盒子中.

注意:对齐容器构建只能放置一个子构件.所以要用盒子构件来帮助布局.

(五)​:Windows

该构件是一个比较常用的构建,我们先看一下在代码中如何使用,再看一下运行之后的结果:

#include 
int main(int argc,char *argv[]){ GtkWidget *window; GtkWidget *table; GtkWidget *title; GtkWidget *activate; GtkWidget *halign; GtkWidget *halign2; GtkWidget *valign; GtkWidget *close; GtkWidget *wins; GtkWidget *help; GtkWidget *ok; gtk_init(&argc,&argv); 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,250); gtk_window_set_resizable(GTK_WINDOW(window),FALSE); gtk_window_set_title(GTK_WINDOW(window),"Windows"); gtk_container_set_border_width(GTK_CONTAINER(window),15); table = gtk_table_new(8,4,FALSE); gtk_table_set_col_spacings(GTK_TABLE(table),3); title = gtk_label_new("Window"); halign = gtk_alignment_new(0,0,0,0); gtk_container_add(GTK_CONTAINER(halign),title); gtk_table_attach(GTK_TABLE(table),halign,0,1,0,1,GTK_FILL,GTK_FILL,0,0); wins = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(wins),FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(wins),FALSE); gtk_table_attach(GTK_TABLE(table),wins,0,2,1,3,GTK_FILL | GTK_EXPAND,GTK_FILL | GTK_EXPAND,1,1); activate = gtk_button_new_with_label("Activate"); gtk_widget_set_size_request(activate,50,30); gtk_table_attach(GTK_TABLE(table),activate,3,4,1,2,GTK_FILL,GTK_FILL,1,1); valign = gtk_alignment_new(0,0,0,0); close = gtk_button_new_with_label("Close"); gtk_widget_set_size_request(close,70,30); gtk_container_add(GTK_CONTAINER(valign),close); gtk_table_set_row_spacing(GTK_TABLE(table),1,3); gtk_table_attach(GTK_TABLE(table),valign,3,4,2,3,GTK_FILL,GTK_FILL | GTK_EXPAND,1,1); halign2 = gtk_alignment_new(0,1,0,0); help = gtk_button_new_with_label("Help"); gtk_container_add(GTK_CONTAINER(halign2),help); gtk_widget_set_size_request(help,70,30); gtk_table_set_row_spacing(GTK_TABLE(table),3,6); gtk_table_attach(GTK_TABLE(table),halign2,0,1,4,5,GTK_FILL,GTK_FILL,0,0); ok = gtk_button_new_with_label("OK"); gtk_widget_set_size_request(ok,70,30); gtk_table_attach(GTK_TABLE(table),ok,3,4,4,5,GTK_FILL,GTK_FILL,0,0); gtk_container_add(GTK_CONTAINER(window),table); g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0;}

下面是运行之后的结果:

在下面的一个小节当中,我们将要了解gtk+图形开发中至关重要的一个问题,就是通过signal来实现事件的监听,同时了解一下信号机制的内部原理。

你可能感兴趣的文章