You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GTK C的Grid组件中居中按钮(控件)

解决GTK Grid组件中按钮居中显示的问题

问题描述

尝试将按钮在GTK的Grid组件中居中显示,已尝试set_halign及相关变体方法但未达到预期效果。当前代码如下,按钮显示偏右:

#include <gtk/gtk.h>

static void ttt_activate(GtkApplication *app){

    GtkWidget *window = gtk_application_window_new (app);
    GtkWidget *grid   = gtk_grid_new();
    GtkWidget *label  = gtk_label_new("Label");

    gtk_window_set_default_size (GTK_WINDOW (window), 800, 800);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 16);
    gtk_grid_set_row_spacing(GTK_GRID(grid), 16);

    // Create buttons 
    GtkWidget * button1 = gtk_button_new_with_label ("button1");
    GtkWidget * button2 = gtk_button_new_with_label ("button2");

    // Attaching buttons
    gtk_grid_attach(GTK_GRID(grid), button1, 5, 3, 2, 3);
    gtk_grid_attach(GTK_GRID(grid), button2, 10, 3, 2, 3);

    // When the button is clicked, close the window passed as an argument
    g_signal_connect_swapped (button1, "clicked", G_CALLBACK (gtk_window_close), window);
    g_signal_connect_swapped (button2, "clicked", G_CALLBACK (gtk_window_close), window);
    gtk_window_set_child(GTK_WINDOW(window), grid);
    gtk_window_present(GTK_WINDOW(window));
}

int main (int argc, char *argv[]) {
  GtkApplication *app = gtk_application_new ("com.example.GtkApplication", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (ttt_activate), NULL);
  return g_application_run (G_APPLICATION (app), argc, argv);
}

问题原因

你将按钮附着到了Grid的第5和第10列,而Grid默认从左到右排列单元格,前面的空列直接导致按钮偏离中心;同时Grid本身在窗口中默认左对齐,进一步加剧了偏移。

解决方案

方法一:让Grid整体在窗口中居中,按钮在Grid内合理排列

这种方法简单直接,通过让Grid整体居中,再调整按钮的附着位置避免空列,实现整体居中效果:

修改后的完整代码:

#include <gtk/gtk.h>

static void ttt_activate(GtkApplication *app){

    GtkWidget *window = gtk_application_window_new (app);
    GtkWidget *grid   = gtk_grid_new();
    GtkWidget *label  = gtk_label_new("Label");

    gtk_window_set_default_size (GTK_WINDOW (window), 800, 800);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 16);
    gtk_grid_set_row_spacing(GTK_GRID(grid), 16);

    // 设置Grid在窗口中水平、垂直居中
    gtk_widget_set_halign(grid, GTK_ALIGN_CENTER);
    gtk_widget_set_valign(grid, GTK_ALIGN_CENTER);

    // Create buttons 
    GtkWidget * button1 = gtk_button_new_with_label ("button1");
    GtkWidget * button2 = gtk_button_new_with_label ("button2");

    // 调整按钮附着位置到Grid起始区域,移除前面的空列
    gtk_grid_attach(GTK_GRID(grid), button1, 0, 0, 2, 3);
    gtk_grid_attach(GTK_GRID(grid), button2, 3, 0, 2, 3);

    // 按钮点击关闭窗口的信号连接
    g_signal_connect_swapped (button1, "clicked", G_CALLBACK (gtk_window_close), window);
    g_signal_connect_swapped (button2, "clicked", G_CALLBACK (gtk_window_close), window);
    
    gtk_window_set_child(GTK_WINDOW(window), grid);
    gtk_window_present(GTK_WINDOW(window));
}

int main (int argc, char *argv[]) {
  GtkApplication *app = gtk_application_new ("com.example.GtkApplication", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (ttt_activate), NULL);
  return g_application_run (G_APPLICATION (app), argc, argv);
}

方法二:让按钮在单元格内居中,Grid占满窗口并均匀分配列宽

如果需要Grid占满整个窗口,按钮在窗口中间区域居中,可以通过设置列均布、单元格内对齐实现:

#include <gtk/gtk.h>

static void ttt_activate(GtkApplication *app){

    GtkWidget *window = gtk_application_window_new (app);
    GtkWidget *grid   = gtk_grid_new();
    GtkWidget *label  = gtk_label_new("Label");

    gtk_window_set_default_size (GTK_WINDOW (window), 800, 800);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 16);
    gtk_grid_set_row_spacing(GTK_GRID(grid), 16);

    // 设置Grid占满窗口可用空间
    gtk_widget_set_hexpand(grid, TRUE);
    gtk_widget_set_vexpand(grid, TRUE);
    // 设置所有列宽度均匀分配
    gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    // 设置所有行高度均匀分配(可选)
    gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);

    // Create buttons 
    GtkWidget * button1 = gtk_button_new_with_label ("button1");
    GtkWidget * button2 = gtk_button_new_with_label ("button2");

    // 设置按钮在单元格内水平、垂直居中
    gtk_widget_set_halign(button1, GTK_ALIGN_CENTER);
    gtk_widget_set_valign(button1, GTK_ALIGN_CENTER);
    gtk_widget_set_halign(button2, GTK_ALIGN_CENTER);
    gtk_widget_set_valign(button2, GTK_ALIGN_CENTER);

    // 将按钮附着到Grid的中间列位置(总列数足够时,6和9列对应窗口中间区域)
    gtk_grid_attach(GTK_GRID(grid), button1, 6, 3, 2, 3);
    gtk_grid_attach(GTK_GRID(grid), button2, 9, 3, 2, 3);

    // 按钮点击关闭窗口的信号连接
    g_signal_connect_swapped (button1, "clicked", G_CALLBACK (gtk_window_close), window);
    g_signal_connect_swapped (button2, "clicked", G_CALLBACK (gtk_window_close), window);
    
    gtk_window_set_child(GTK_WINDOW(window), grid);
    gtk_window_present(GTK_WINDOW(window));
}

int main (int argc, char *argv[]) {
  GtkApplication *app = gtk_application_new ("com.example.GtkApplication", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (ttt_activate), NULL);
  return g_application_run (G_APPLICATION (app), argc, argv);
}

内容的提问来源于stack exchange,提问作者Li En

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:54:57