GTK提供了许多不同的容器组件,用户可以通过搭配不同的容器组件来控制子组件的布局方式。
容器组件如下:
- GtkBox
- GtkGrid
- GtkRevealer
- GtkStack
- GtkOverlay
- GtkPaned
- GtkExpander
- GtkFixed
1、GtkBox
GtkBox会将子组件以水平或垂直的方式布局。
在创建GtkBox容器传入的GtkOrientation参数将决定GtkBox是以水平还是垂直的方式组织子组件。
所有组件的大小都是一样的。
gtk_box_append:向GtkBox中添加子组件;
gtk_box_remove:从GtkBox中移除子组件;
gtk_box_insert_child_after:在特定位置添加子组件;
gtk_box_set_homogeneous:是否对GtkBox中的子组件强制分配相同的空间;
gtk_box_set_spacing:设置子组件之间的间隔距离;
gtk_box_reorder_child_after:移动子组件位置;
2、GtkGrid
GtkGrid容器将子组件以网格的方式进行组织。
在这个容器中可以随意指定子组件的具体位置和子组件占据的行数与列数。
gtk_grid_attach:向容器中添加子组件;
gtk_grid_attach_next_to:在已存在的子组件后一个位置放置组件;
gtk_grid_remove:从grid中移除子组件;
3、GtkRevealer
该容器用于将他的子组件由不可见转为可见。
如果想要自定义过渡动画,可以通过gtk_revealer_set_transition_type函数进行设置。
gtk_revealer_new:创建GtkRevealer对象。
该容器只能有一个子组件。
示例如下:
点击查看代码
#include <gtk/gtk.h>
#include "common_macro.h"
#define LABEL1 "button1"
#define WIN_TITLE "GtkRevealer Test"
LOCAL void clicked(GtkButton *btn, gpointer user_data)
{
g_print("hide");
gtk_revealer_set_reveal_child((GtkRevealer *)user_data, FALSE);
}
LOCAL void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *win = gtk_application_window_new(app);
GtkWidget *revealer = gtk_revealer_new();
GtkWidget *btn = gtk_button_new_with_label(LABEL1);
gtk_revealer_set_child((GtkRevealer *)revealer, btn);
gtk_revealer_set_reveal_child((GtkRevealer *)revealer, TRUE);
g_signal_connect(btn, SIGNAL_CLICKED, G_CALLBACK(clicked), revealer);
gtk_window_set_title(GTK_WINDOW(win), WIN_TITLE);
gtk_window_set_default_size(GTK_WINDOW(win), 200, 200);
gtk_window_set_child(GTK_WINDOW(win), revealer);
gtk_window_present(GTK_WINDOW(win));
}
int main(int argc, char **argv)
{
GtkApplication *app = NULL;
int status = 0;
app = gtk_application_new(APP_ID, G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, SIGNAL_ACTIVATE, G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
4、GtkStack
GtkStack和数据机构中的堆栈类似,同一时间只会显示顶层组件。
与GtkNotebook相比,GtkStack没有为用户提供更改可见子节点的方法。相反,GtkStackSwitcher或GtkStackSidebar等单独的小部件可以与GtkStack一起使用来提供此功能。
页面之间的切换动画可以通过gtk_stack_set_transition_type方法进行控制。
GtkStack为每个添加的子节点维护一个GtkStackPage对象,该对象保存每个子节点的额外属性。您可以使用gtk_stack_get_page()获得子节点的GtkStackPage,并且可以使用gtk_stack_get_pages()获得包含所有页面的GtkSelectionModel对象。
示例如下:
点击查看代码
#include <gtk/gtk.h>
#include "common_macro.h"
#define WIN_TITLE "GtkStack Test"
gboolean switch_btn = FALSE;
LOCAL void clicked(GtkButton *btn, gpointer user_data)
{
g_print(gtk_button_get_label(btn));
GtkSelectionModel *model = gtk_stack_get_pages(GTK_STACK(user_data));
if (switch_btn) {
gtk_selection_model_select_item(model, 0, TRUE);
switch_btn = FALSE;
} else {
switch_btn = TRUE;
gtk_selection_model_select_item(model, 1, TRUE);
}
}
LOCAL void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *win = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(win), WIN_TITLE);
gtk_window_set_default_size(GTK_WINDOW(win), 200, 200);
GtkWidget *stack = gtk_stack_new();
GtkWidget *btn1 = gtk_button_new_with_label("button1");
GtkWidget *btn2 = gtk_button_new_with_label("button2");
GtkWidget *btn3 = gtk_button_new_with_label("button3");
gtk_window_set_child(GTK_WINDOW(win), stack);
gtk_stack_add_child(GTK_STACK(stack), btn1);
gtk_stack_add_child(GTK_STACK(stack), btn2);
g_signal_connect(btn1, SIGNAL_CLICKED, G_CALLBACK(clicked), stack);
g_signal_connect(btn2, SIGNAL_CLICKED, G_CALLBACK(clicked), stack);
gtk_window_present(GTK_WINDOW(win));
}
int main(int argc, char **argv)
{
GtkApplication *app = NULL;
int status = 0;
app = gtk_application_new(APP_ID, G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, SIGNAL_ACTIVATE, G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
5、GtkOverlay
GtkOverlay只能放置一个子组件,这个子组件的上面可以放置覆盖组件。
overlay组件的具体位置由GtkWidget:halign
和GtkWidget:valign
属性指定。例如,当组件的垂直和水平对齐都被设置为GTK_ALIGN_START
,那么这个组件就会被放置在GtkOverlay容器的左上角。
这个容器主要用于将一个组件放置在另一个组件之上。
点击查看代码
#include<gtk/gtk.h>
#include"common_macro.h"
LOCAL void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *overlay = gtk_overlay_new();
GtkWidget *btn1 = gtk_button_new_with_label("button1");
gtk_overlay_set_child(GTK_OVERLAY(overlay), btn1);
GtkWidget *win = gtk_application_window_new(app);
gtk_window_set_default_size(GTK_WINDOW(win), 200, 200);
gtk_window_set_title(GTK_WINDOW(win), "GtkOverlay Test");
gtk_window_set_child(GTK_WINDOW(win), overlay);
GtkWidget *btn2 = gtk_button_new_with_label("button2");
gtk_widget_set_halign(btn2, GTK_ALIGN_START);
gtk_overlay_add_overlay(GTK_OVERLAY(overlay), btn2);
gtk_window_present(GTK_WINDOW(win));
}
int main(int argc, char **argv)
{
GtkApplication *app = NULL;
int status = 0;
app = gtk_application_new(APP_ID, G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, SIGNAL_ACTIVATE, G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
6、GtkPaned
GtkPaned组件拥有两个窗格,水平或者垂直。
用户可以通过拉动窗格分界线,调整两个窗格的比例。
通过gtk_paned_set_start_child和gtk_paned_set_end_child方法在两个窗格中添加子组件。这两个窗格之间的比例是子组件大小默认设置的,但是用户可以进行调整。
通常都是讲子组件放到GtkFrame中,然后再讲GtkFrame放到窗格中。如果只设置了一个窗格,那么将不会绘制分隔符。
每个子组件都有两个可以设置的选项,“resize”和“shrink”。如果设置为resize,那么当GtkPaned尺寸变化时,那么子组件的大小也会跟着变化。如果设置为“shrink”,那么子组件的大小会变得更小。
可以通过调用gtk_paned_set_position函数设置滑动条的位置。
点击查看代码
#include<gtk/gtk.h>
#include"common_macro.h"
LOCAL void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
GtkWidget *btn1 = gtk_button_new_with_label("button1");
GtkWidget *win = gtk_application_window_new(app);
gtk_window_set_default_size(GTK_WINDOW(win), 200, 200);
gtk_window_set_title(GTK_WINDOW(win), "GtkPaned Test");
gtk_window_set_child(GTK_WINDOW(win), paned);
GtkWidget *btn2 = gtk_button_new_with_label("button2");
gtk_paned_set_start_child(GTK_PANED(paned), btn1);
gtk_paned_set_end_child(GTK_PANED(paned), btn2);
gtk_window_present(GTK_WINDOW(win));
}
int main(int argc, char **argv)
{
GtkApplication *app = NULL;
int status = 0;
app = gtk_application_new(APP_ID, G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, SIGNAL_ACTIVATE, G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
7、GtkExpander
GtkExpander
可以让用户点击扩展三角形显示子元素。
如果想要在点击展开的时候进行自定义行为,可以使用notify::expanded
信号。文章来源:https://www.toymoban.com/news/detail-663464.html
点击查看代码
#include<gtk/gtk.h>
#include"common_macro.h"
LOCAL void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *expander = gtk_expander_new("Test");
GtkWidget *win = gtk_application_window_new(app);
gtk_window_set_default_size(GTK_WINDOW(win), 200, 200);
gtk_window_set_title(GTK_WINDOW(win), "GtkExpander Test");
gtk_window_set_child(GTK_WINDOW(win), expander);
GtkWidget *btn1 = gtk_button_new_with_label("btn1");
gtk_expander_set_child(GTK_EXPANDER(expander), btn1);
gtk_window_present(GTK_WINDOW(win));
}
int main(int argc, char **argv)
{
GtkApplication *app = NULL;
int status = 0;
app = gtk_application_new(APP_ID, G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, SIGNAL_ACTIVATE, G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
8、GtkFixed
GtkFixed
容器的子元素位置和尺寸大小都是固定的。
该容器不会自动适应容器变化。
不推荐使用该容器,因为它可能会导致文本截断、组件覆盖以及其他的显示问题。文章来源地址https://www.toymoban.com/news/detail-663464.html
点击查看代码
#include<gtk/gtk.h>
#include"common_macro.h"
LOCAL void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *fixed = gtk_fixed_new();
GtkWidget *win = gtk_application_window_new(app);
gtk_window_set_default_size(GTK_WINDOW(win), 200, 200);
gtk_window_set_title(GTK_WINDOW(win), "GtkFixed Test");
gtk_window_set_child(GTK_WINDOW(win), fixed);
GtkWidget *btn1 = gtk_button_new_with_label("btn1");
gtk_fixed_put(GTK_FIXED(fixed), btn1, 10, 10);
gtk_window_present(GTK_WINDOW(win));
}
int main(int argc, char **argv)
{
GtkApplication *app = NULL;
int status = 0;
app = gtk_application_new(APP_ID, G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, SIGNAL_ACTIVATE, G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
到了这里,关于【GTK】布局容器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!