# PHP GTK 中的布局管理

> 原文： [http://zetcode.com/gui/phpgtktutorial/layoutmanagement/](http://zetcode.com/gui/phpgtktutorial/layoutmanagement/)

在本章中，我们将展示如何在窗口或对话框中布置窗口小部件。

在设计应用的 GUI 时，我们决定要使用哪些小部件以及如何在应用中组织这些小部件。 为了组织窗口小部件，我们使用专门的不可见窗口小部件，称为布局容器。 在本章中，我们将提到`GtkAlignment`，`GtkFixed`，`GtkVBox`和`GtkTable`。

## `GtkFixed`

`GtkFixed`容器将子窗口小部件放置在固定位置并具有固定大小。 此容器不执行自动布局管理。 在大多数应用中，我们不使用此容器。 我们在某些专业领域使用它。 例如游戏，使用图表的专用应用，可以移动的可调整大小的组件（如电子表格应用中的图表），小型教育示例。

```php
<?php

/* 
ZetCode PHP GTK tutorial

In this program, we lay out widgets
using absolute positioning.

author: Jan Bodnar
website: www.zetcode.com
last modified: September 2011
*/

class Example extends GtkWindow { 

    public function __construct() { 

        parent::__construct(); 

        $this->init_ui();

    } 

    public function init_ui() {

        $this->set_title('Fixed');         
        $this->connect_simple('destroy', array('gtk', 'main_quit')); 

        $this->modify_bg(Gtk::STATE_NORMAL, new GdkColor(6400, 6400, 6440));

        $bardejov = GtkImage::new_from_file("bardejov.jpg");
        $rotunda = GtkImage::new_from_file("rotunda.jpg");
        $mincol = GtkImage::new_from_file("mincol.jpg");

        $fixed = new GtkFixed();
        $fixed->put($bardejov, 20, 20);
        $fixed->put($rotunda, 40, 160);
        $fixed->put($mincol, 170, 50);

        $this->add($fixed);        

        $this->set_default_size(300, 280); 
        $this->set_position(GTK::WIN_POS_CENTER);
        $this->show_all();         

    }
} 

new Example(); 
Gtk::main();

?>

```

在我们的示例中，我们在窗口上显示了三个小图像。 我们明确指定放置这些图像的 x，y 坐标。

```php
$this->modify_bg(Gtk::STATE_NORMAL, new GdkColor(6400, 6400, 6440));

```

为了获得更好的视觉体验，我们将背景色更改为深灰色。

```php
$bardejov = GtkImage::new_from_file("bardejov.jpg");

```

`GtkImage`是用于显示图像的小部件。 图片是从磁盘上的文件加载的。

```php
$fixed = new GtkFixed();

```

我们创建`GtkFixed`容器。

```php
$fixed->put($bardejov, 20, 20);

```

我们将第一个图像放置在`x = 20`，`y = 20`坐标处。

```php
w.add(fixed);

```

最后，我们将`GtkFixed`容器添加到窗口中。

![Fixed](img/2173f81617eeacc52ede7d9759e0fd34.jpg)

图：固定

## 按钮

在此代码示例中，我们将使用垂直框，水平框和路线小部件。 水平框将小部件排列为一行。 同样，垂直框将其小部件放在一列中。 `Alignment`容器控制其子窗口小部件的对齐方式和大小。

```php
<?php

/* 
ZetCode PHP GTK tutorial

In this program, we position two buttons
in the bottom right corner of the window.
We use horizontal and vertical boxes.

author: Jan Bodnar
website: www.zetcode.com
last modified: August 2011
*/

class Example extends GtkWindow { 

    public function __construct() { 

        parent::__construct(); 

        $this->init_ui();

    } 

    public function init_ui() {

        $this->set_title('Buttons');         
        $this->connect_simple('destroy', array('gtk', 'main_quit')); 
        $this->set_border_width(3);

        $vbox = new GtkVBox(false, 5);
        $hbox = new GtkHBox(true, 3);

        $frame = new GtkFrame();
        $vbox->pack_start($frame, true, true, 0);

        $okButton = new GtkButton("OK");
        $okButton->set_size_request(70, 30);
        $closeButton = new GtkButton("Close");

        $hbox->add($okButton);
        $hbox->add($closeButton);

        $halign = new GtkAlignment(1, 0, 0, 0);
        $halign->add($hbox);
        $vbox->pack_start($halign, false, false, 3);

        $this->add($vbox);        

        $this->set_default_size(260, 150); 
        $this->set_position(GTK::WIN_POS_CENTER);
        $this->show_all();          
    }
} 

new Example(); 
Gtk::main();

?>

```

在代码示例中，我们在窗口的右下角放置了两个按钮。 为此，我们使用一个水平框，一个垂直框和一个对齐容器。

```php
$vbox = new GtkVBox(false, 5);

```

将创建一个垂直框容器。 我们将同构成员设置为`false`。 这意味着放在垂直框中的窗口小部件将具有相同的大小。 小部件之间的垂直间距设置为 5 像素。

```php
$frame = new GtkFrame();

```

在这里，我们创建一个`GtkFrame`小部件。 该小部件的目的是占用两个按钮上方的空间。

```php
$vbox->pack_start($frame, true, true, 0);

```

在这里，我们将框架小部件放入垂直框中。 该方法的第一个参数是小部件，它被放置在框中。 以下三个参数是`expand`，`fill`和`padding`。 `expand`参数设置为`true`，这意味着将在小部件周围分配可用空间。 当`fill`参数设置为`true`时，小部件实际上会占用其周围的所有可用空间。 子窗口小部件周围没有填充。

```php
$hbox = new GtkHBox(true, 3);  

```

此代码行创建一个水平框。 框内的所有小部件都将具有相同的大小。 小部件之间的水平间隔为 3px。

```php
$okButton = new GtkButton("OK");
$okButton->set_size_request(70, 30);
$closeButton = new GtkButton("Close");

$hbox->add($okButton);
$hbox->add($closeButton);

```

我们创建两个按钮，并将它们放在水平框中。

```php
$halign = new GtkAlignment(1, 0, 0, 0);
$halign->add($hbox);
$vbox->pack_start($halign, false, false, 3);

```

这将创建一个对齐容器，它将其子窗口小部件放在右侧。 设置为 1.0 的`xalign`成员会将所有可用空间放在水平框的左侧。 这将向右推两个按钮。 我们将水平框添加到对齐容器中，然后将对齐容器包装到垂直框中。 我们必须记住，对齐容器仅包含一个子窗口小部件。 这就是为什么我们必须使用水平框。

![Buttons](img/0c5591316bc5ff6879391b1c34c9bd6e.jpg)

图：按钮

## 计算器骨架

`GtkTable`小部件按行和列排列小部件。

```php
<?php

/* 
ZetCode PHP GTK tutorial

In this program we create a skeleton of
a calculator. We use the GtkTable widget.

author: Jan Bodnar
website: www.zetcode.com
last modified: August 2011
*/

class Example extends GtkWindow { 

    public function __construct() { 

        parent::__construct(); 

        $this->init_ui();

    } 

    public function init_ui() {

        $this->set_title('Calculator');         
        $this->connect_simple('destroy', array('gtk', 'main_quit')); 

        $vbox = new GtkVBox(false, 2);

        $mb = new GtkMenubar();
        $filemenu = new GtkMenu();
        $filemi = new GtkMenuItem("File");
        $filemi->set_submenu($filemenu);
        $mb->append($filemi);

        $vbox->pack_start($mb, false, false, 0);

        $table = new GtkTable(5, 4, true);

        $table->attach_defaults(new GtkButton("Cls"), 0, 1, 0, 1);
        $table->attach_defaults(new GtkButton("Bck"), 1, 2, 0, 1);
        $table->attach_defaults(new GtkLabel(), 2, 3, 0, 1);
        $table->attach_defaults(new GtkButton("Close"), 3, 4, 0, 1);

        $table->attach_defaults(new GtkButton("7"), 0, 1, 1, 2);
        $table->attach_defaults(new GtkButton("8"), 1, 2, 1, 2);
        $table->attach_defaults(new GtkButton("9"), 2, 3, 1, 2);
        $table->attach_defaults(new GtkButton("/"), 3, 4, 1, 2);

        $table->attach_defaults(new GtkButton("4"), 0, 1, 2, 3);
        $table->attach_defaults(new GtkButton("5"), 1, 2, 2, 3);
        $table->attach_defaults(new GtkButton("6"), 2, 3, 2, 3);
        $table->attach_defaults(new GtkButton("*"), 3, 4, 2, 3);

        $table->attach_defaults(new GtkButton("1"), 0, 1, 3, 4);
        $table->attach_defaults(new GtkButton("2"), 1, 2, 3, 4);
        $table->attach_defaults(new GtkButton("3"), 2, 3, 3, 4);
        $table->attach_defaults(new GtkButton("-"), 3, 4, 3, 4);

        $table->attach_defaults(new GtkButton("0"), 0, 1, 4, 5);
        $table->attach_defaults(new GtkButton("."), 1, 2, 4, 5);
        $table->attach_defaults(new GtkButton("="), 2, 3, 4, 5);
        $table->attach_defaults(new GtkButton("+"), 3, 4, 4, 5);

        $vbox->pack_start(new GtkEntry(), false, false, 0);
        $vbox->pack_end($table, true, true, 0);

        $this->add($vbox);        

        $this->set_default_size(300, 250); 
        $this->set_position(GTK::WIN_POS_CENTER);
        $this->show_all();         

    }
} 

new Example(); 
Gtk::main();

?>

```

我们使用`GtkTable`小部件创建一个计算器框架。

```php
$table = new GtkTable(5, 4, true);

```

我们创建一个具有 5 行 4 列的表小部件。 第三个参数是同质参数。 如果设置为`true`，则表中的所有小部件都具有相同的大小。 所有窗口小部件的大小等于表容器中最大的窗口小部件。

```php
$table->attach_defaults(new GtkButton("Cls"), 0, 1, 0, 1);

```

我们在表格容器上附加一个按钮。 到表格的左上方单元格。 前两个参数是单元格的左侧和右侧，后两个参数是单元格的顶部和左侧。

```php
$vbox->pack_end($table, true, true, 0);

```

我们将表格小部件打包到垂直框中。

![Calculator skeleton](img/0bf29b4526c0261cc58083d118e5a28b.jpg)

图：计算机骨架

## 窗口

接下来，我们将创建一个更高级的示例。 我们显示一个窗口，可以在 JDeveloper IDE 中找到它。

```php
<?php

/* 
ZetCode PHP GTK tutorial

This is a more complicated layout example.
We use GtkAlignment and GtkTable widgets. 

author: Jan Bodnar
website: www.zetcode.com
last modified: August 2011
*/

class Example extends GtkWindow { 

    public function __construct() { 

        parent::__construct(); 

        $this->init_ui();
    } 

    public function init_ui() {

        $this->set_title('Windows');         
        $this->connect_simple('destroy', array('gtk', 'main_quit')); 

        $this->set_border_width(15);

        $table = new GtkTable(8, 4, false);
        $table->set_col_spacings(3);

        $title = new GtkLabel("Windows");

        $halign = new GtkAlignment(0, 0, 0, 0);
        $halign->add($title);        
        $table->attach($halign, 0, 1, 0, 1, GTK::FILL, 
            GTK::FILL, 0, 0);

        $frame = new GtkFrame();
        $table->attach($frame, 0, 2, 1, 3, GTK::FILL | Gtk::EXPAND,
            GTK::FILL | GTK::EXPAND, 1, 1);

        $activate = new GtkButton("Activate");
        $activate->set_size_request(50, 30);
        $table->attach($activate, 3, 4, 1, 2, GTK::FILL,
            GTK::SHRINK, 1, 1);

        $valign = new GtkAlignment(0, 0, 0, 0);
        $close = new GtkButton("Close");
        $close->set_size_request(70, 30);
        $valign->add($close);
        $table->set_row_spacing(1, 3);
        $table->attach($valign, 3, 4, 2, 3, Gtk::FILL,
            Gtk::FILL | Gtk::EXPAND, 1, 1);

        $halign2 = new GtkAlignment(0, 1, 0, 0);
        $help = new GtkButton("Help");
        $help->set_size_request(70, 30);
        $halign2->add($help);
        $table->set_row_spacing(3, 6);
        $table->attach($halign2, 0, 1, 4, 5, Gtk::FILL,
            Gtk::FILL, 0, 0);

        $ok = new GtkButton("OK");
        $ok->set_size_request(70, 30);
        $table->attach($ok, 3, 4, 4, 5, Gtk::FILL,
            Gtk::FILL, 0, 0);

        $this->add($table);        

        $this->set_default_size(300, 250); 
        $this->set_position(GTK::WIN_POS_CENTER);
        $this->show_all();         
    }
} 

new Example(); 
Gtk::main();

?>

```

该代码示例显示了如何在 PHP GTK 中创建类似的窗口。

```php
$table = new GtkTable(8, 4, false);
$table->set_col_spacings(3);

```

该示例基于`GtkTable`容器。 列之间将有 3px 的间隔。

```php
$title = new GtkLabel("Windows");

$halign = new GtkAlignment(0, 0, 0, 0);
$halign->add($title);        
$table->attach($halign, 0, 1, 0, 1, GTK::FILL, 
    GTK::FILL, 0, 0);

```

这段代码创建了一个向左对齐的标签。 标签放置在`Table`容器的第一列的第一行中。

```php
$frame = new GtkFrame();
$table->attach($frame, 0, 2, 1, 3, GTK::FILL | Gtk::EXPAND,
    GTK::FILL | GTK::EXPAND, 1, 1);

```

框架小部件跨越两行两列。 它将消耗其周围的所有可用空间。 因此，占用了窗口的大部分区域。

```php
$valign = new GtkAlignment(0, 0, 0, 0);
$close = new GtkButton("Close");
$close->set_size_request(70, 30);
$valign->add($close);
$table->set_row_spacing(1, 3);
$table->attach($valign, 3, 4, 2, 3, Gtk::FILL,
    Gtk::FILL | Gtk::EXPAND, 1, 1);

```

我们将关闭按钮放在框架小部件旁边，进入第四列。 （我们从零开始计数）将按钮添加到对齐小部件中，以便可以将其对齐到顶部。

```php
$halign2 = new GtkAlignment(0, 1, 0, 0);
$help = new GtkButton("Help");
$help->set_size_request(70, 30);
$halign2->add($help);
$table->set_row_spacing(3, 6);
$table->attach($halign2, 0, 1, 4, 5, Gtk::FILL,
    Gtk::FILL, 0, 0);

```

将帮助按钮放置在对齐小部件中，以便可以在其表格单元格中使其对齐。 它位于第一列第五行。

```php
$ok = new GtkButton("OK");
$ok->set_size_request(70, 30);
$table->attach($ok, 3, 4, 4, 5, Gtk::FILL,
    Gtk::FILL, 0, 0);

```

最后，单击确定按钮。 它位于第四列和第五行。

![Windows](img/6ee2603ecc25a0ffb3ddeabe847e028e.jpg)

图：窗口

在 PHP GTK 教程的这一部分中，我们提到了小部件的布局管理。