让我们看看另一种布局控件的方法 - 表(Tables)。

在某些情况下使用 Table 进行控件的布局是极其有用的哟。

使用 Table 控件的时候,我们建立单元格来放入控件,控件可以占满我们所指定的所有单元格空间。

gtk_table_new()

第一个要看的,当然是 gtk_table_new() 这个函数:

GtkWidget *gtk_table_new( guint    rows,
                          guint    columns,
                          gboolean homogeneous );

参数:

  • rows
    第一个参数是表中要安排的行的数量;
  • columns
    第二个参数是表中要安排的列的数量;
  • homogeneous
    homogeneous 参数跟表格框(table’s boxes)的大小处理有关;
    如果 homogeneous 是 TRUE,所有单元格的大小都将调整为表中最大控件的大小,也就是单元格适配里面的控件;
    如果 homogeneous 为 FALSE,每个表格框将会按照同行中最高的控件,与同列中最宽的控件来决定自身的大小;

布局图示意图 (以2行2列为例)

行与列为从0到n编号,而n是我们在调用 gtk_table_new 时所指定的值。所以,如果你指定 rows = 2 及 columns = 2, 布局图会看起来像这样:

 0          1          2
0+----------+----------+
 |          |          |
1+----------+----------+
 |          |          |
2+----------+----------+ 

注意:

  1. 坐标系统开始于左上角
  2. 虚线索引值为 gtk_table_attach() 的 left_attach、right_attach、top_attach、bottom_attach的参数值,放置的控件的四个边对应上单元格虚线即可;

gtk_table_attach()

要向框中放置一个控件,使用下面的函数:

void gtk_table_attach( GtkTable         *table,
                       GtkWidget        *child,

                       guint            left_attach,  //对应被放置控件的最左边
                       guint            right_attach, //对应被放置控件的最右边
                       guint            top_attach,   //对应被放置控件的最上边
                       guint            bottom_attach,//对应被放置控件的最下边

                       GtkAttachOptions xoptions,
                       GtkAttachOptions yoptions,

                       guint            xpadding,
                       guint            ypadding );

参数:

  • table
    第一个参数(”table”)是你已经创建的表
  • child
    第二个参数(”child”)是你想放进表里的控件。
  • left_attach、right_attach、top_attach、bottom_attach
    left_attach和right_attach参数指定控件放置的位置,并使用多少框来放。
    简单记忆:布局示意图的虚线作为开始和结束的参考位置!!!
    如果你想在2x2的表中的右下表项(table entry)处放入一个按钮,并且想让它只充满这个项,则:
    left_attach = 1, right_attach = 2, top_attach = 1, bottom_attach = 2。
    如果你想让一个控件占据我们这个2x2表的整个顶行,你就用:
    left_attach = 0, right_attach = 2, top_attach = 0, bottom_attach = 1。
  • xoptions、yoptions
    xoptions及yoptions是用来指定组装时的选项,可以通过使用“位或”运算以允许多重选项。
    这些选项是:
    GTK_FILL - 如果表框大于控件,同时GTK_FILL被指定,该控件会扩展开以使用所有可用的空间。
    GTK_SHRINK - 如果表控件分配到的空间比需求的小(通常是用户在改变窗口大小的时候),那么控件将会推到窗口的底部以外的区域,无法看见。如果GTK_SHRINK被指定了,控件将和表一起缩小。
    GTK_EXPAND - 这会导致表扩展以用完窗口中所有的保留空间。
  • xpadding、ypadding
    Padding和在盒(boxes)中的一样,在控件的周围产生一个指定象素的空白区域。

gtk_table_attach_defaults()

因为上面的gtk_table_attach()有很多选项,所以,这里有一个简写形式:

void gtk_table_attach_defaults( GtkTable  *table,
                                GtkWidget *widget,

                                guint      left_attach,
                                guint      right_attach,
                                guint      top_attach,
                                guint      bottom_attach );

参数:

  • gtk_table_attach()函数中的xoptions、yoptions参数
    X及Y选项默认为GTK_FILL | GTK_EXPAND
  • gtk_table_attach()函数中的xpadding、ypadding参数
    X和Y的padding则设为0。
  • 其余的参数与前面的gtk_table_attach()函数一样。

gtk_table_set_row_spacing() 和 gtk_table_set_col_spacing()

我们还有 gtk_table_set_row_spacing() 和 gtk_table_set_col_spacing()。这些在指定的行或列之间插入空白。

void gtk_table_set_row_spacing( GtkTable *table,
                                guint     row,
                                guint     spacing );

void gtk_table_set_col_spacing ( GtkTable *table,
                                 guint     column,
                                 guint     spacing );

注意:

  • 来说,空白插入行的下边
  • 来说,空白插到列的右边

gtk_table_set_row_spacings() 和 gtk_table_set_col_spacings()

也可以为所有的行或和列设置相同的间隔:

void gtk_table_set_row_spacings( GtkTable *table,
                                 guint    spacing );

和,

void gtk_table_set_col_spacings( GtkTable *table,
                                 guint     spacing );

注意:如果是最后一行和最后一列,则不会产生任何空白

示例

界面设计效果

table控件 - 图1


界面放置的控件要求:

  • 创建一个包含一个 2x2 表的窗口,表中放入三个按钮;
  • 前两个按钮button1 和 button2 放在表的第一行;
  • 第三个按钮为 Quit按钮,放在第二行,并占据了两列;

这里是源代码:

/*文件名: main.c */

#include <gtk/gtk.h>

/* 回调函数
 * 传到这个函数的数据被打印到标准输出 */
void callback( GtkWidget *widget,
               gpointer   data )
{
    g_print ("Hello again - %s was pressed\n", (char *) data);
}

/* 这个回调函数为:退出程序 */
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
                   gpointer   data )
{
    gtk_main_quit ();
    return FALSE;
}

int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *table;

    gtk_init (&argc, &argv);

    /* 创建一个新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    /* 设置窗口标题 */
    gtk_window_set_title (GTK_WINDOW (window), "www.softool.cn Table");

    /* 为delete_event设置一个立即退出GTK的处理函数。 */
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);

    /* 设置窗口的边框宽度为: 20px*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 20);

    /* 创建一个2x2的表,即:2行2列 */
    table = gtk_table_new (2, 2, TRUE);

    /* 将表放进主窗口 */
    gtk_container_add (GTK_CONTAINER (window), table);

    /* 创建第一个按钮:button 1 */
    button = gtk_button_new_with_label ("button 1");
    /* 当这个按钮被点击时,我们调用 "callback" 函数,并将一个
     * 指向"button 1"的指针作为它的参数 */
    g_signal_connect (G_OBJECT (button), "clicked",
                  G_CALLBACK (callback), (gpointer) "button 1");
    /* 将button 1插入表的左上象限(quadrant) */
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 0, 1);
    gtk_widget_show (button);

    /* 创建第二个按钮:button 2 */
    button = gtk_button_new_with_label ("button 2");
    /* 当这个按钮被点击时,我们调用 "callback" 函数,并将一个
     * 指向"button 2"的指针作为它的参数 */
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (callback), (gpointer) "button 2");
    /* 将button 2插入表的右上象限 */
    gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, 0, 1);
    gtk_widget_show (button);

    /* 创建第三个按钮:"Quit"按钮 */
    button = gtk_button_new_with_label ("Quit");
    /* 当这个按钮被点击时,我们调用 "delete_event" 函数接着
     * 程序就退出了 */
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (delete_event), NULL);
    /* 将退出按钮插入表的下面两个象限 */
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 2, 1, 2);
    gtk_widget_show (button);

    gtk_widget_show (table);
    gtk_widget_show (window);

    gtk_main ();

    return 0;
}