【GTK】布局容器

这篇具有很好参考价值的文章主要介绍了【GTK】布局容器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

GTK提供了许多不同的容器组件,用户可以通过搭配不同的容器组件来控制子组件的布局方式。
容器组件如下:

  • GtkBox
  • GtkGrid
  • GtkRevealer
  • GtkStack
  • GtkOverlay
  • GtkPaned
  • GtkExpander
  • GtkFixed

1、GtkBox

GtkBox会将子组件以水平或垂直的方式布局。
【GTK】布局容器
在创建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】布局容器
在这个容器中可以随意指定子组件的具体位置和子组件占据的行数与列数。
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只能放置一个子组件,这个子组件的上面可以放置覆盖组件。
【GTK】布局容器
overlay组件的具体位置由GtkWidget:halignGtkWidget: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】布局容器
用户可以通过拉动窗格分界线,调整两个窗格的比例。
通过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可以让用户点击扩展三角形显示子元素。
【GTK】布局容器
如果想要在点击展开的时候进行自定义行为,可以使用notify::expanded信号。

点击查看代码
#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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包