💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# GTK# 中的布局管理 > 原文: [http://zetcode.com/gui/gtksharp/layout/](http://zetcode.com/gui/gtksharp/layout/) 在本章中,我们将展示如何在窗口或对话框中布置窗口小部件。 在设计应用的 GUI 时,我们决定要使用哪些小部件以及如何在应用中组织这些小部件。 为了组织窗口小部件,我们使用专门的不可见窗口小部件,称为布局容器。 在本章中,我们将提到`Alignment`,`Fixed`,`VBox`和`Table`。 ## `Fixed` `Fixed`容器将子窗口小部件放置在固定位置并具有固定大小。 此容器不执行自动布局管理。 在大多数应用中,我们不使用此容器。 我们在某些专业领域使用它。 例如游戏,使用图表的专用应用,可以移动的可调整大小的组件(如电子表格应用中的图表),小型教育示例。 `fixed.cs` ```cs using Gtk; using System; class SharpApp : Window { private Gdk.Pixbuf rotunda; private Gdk.Pixbuf bardejov; private Gdk.Pixbuf mincol; public SharpApp() : base("Fixed") { SetDefaultSize(300, 280); SetPosition(WindowPosition.Center); ModifyBg(StateType.Normal, new Gdk.Color(40, 40, 40)); DeleteEvent += delegate { Application.Quit(); }; try { bardejov = new Gdk.Pixbuf("bardejov.jpg"); rotunda = new Gdk.Pixbuf("rotunda.jpg"); mincol = new Gdk.Pixbuf("mincol.jpg"); } catch { Console.WriteLine("Images not found"); Environment.Exit(1); } Image image1 = new Image(bardejov); Image image2 = new Image(rotunda); Image image3 = new Image(mincol); Fixed fix = new Fixed(); fix.Put(image1, 20, 20); fix.Put(image2, 40, 160); fix.Put(image3, 170, 50); Add(fix); ShowAll(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } } ``` 在我们的示例中,我们在窗口上显示了三个小图像。 我们明确指定放置这些图像的 x,y 坐标。 ```cs ModifyBg(StateType.Normal, new Gdk.Color(40, 40, 40)); ``` 为了获得更好的视觉体验,我们将背景色更改为深灰色。 ```cs bardejov = new Gdk.Pixbuf("bardejov.jpg"); ``` 我们将图像从磁盘加载到`Gdk.Pixbuf`对象。 ```cs Image image1 = new Image(bardejov); Image image2 = new Image(rotunda); Image image3 = new Image(mincol); ``` `Image`是用于显示图像的小部件。 它在构造器中使用`Gdk.Pixbuf`对象。 ```cs Fixed fix = new Fixed(); ``` 我们创建`Fixed`容器。 ```cs fix.Put(image1, 20, 20); ``` 我们将第一个图像放置在`x = 20`,`y = 20`坐标处。 ```cs Add(fix); ``` 最后,我们将`Fixed`容器添加到窗口中。 ![Fixed](https://img.kancloud.cn/e0/73/e073300df12029fbff7cbb73a9b6288e_308x308.jpg) 图:固定 ## `Alignment` `Alignment`容器控制其子窗口小部件的对齐方式和大小。 `alignment.cs` ```cs using Gtk; using System; class SharpApp : Window { public SharpApp() : base("Alignment") { SetDefaultSize(260, 150); SetPosition(WindowPosition.Center); DeleteEvent += delegate { Application.Quit(); }; VBox vbox = new VBox(false, 5); HBox hbox = new HBox(true, 3); Alignment valign = new Alignment(0, 1, 0, 0); vbox.PackStart(valign); Button ok = new Button("OK"); ok.SetSizeRequest(70, 30); Button close = new Button("Close"); hbox.Add(ok); hbox.Add(close); Alignment halign = new Alignment(1, 0, 0, 0); halign.Add(hbox); vbox.PackStart(halign, false, false, 3); Add(vbox); ShowAll(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } } ``` 在代码示例中,我们在窗口的右下角放置了两个按钮。 为此,我们使用一个水平框和一个垂直框以及两个对齐容器。 ```cs Alignment valign = new Alignment(0, 1, 0, 0); ``` 这会将子窗口小部件置于底部。 ```cs vbox.PackStart(valign); ``` 在这里,我们将`Alignment`小部件放置到垂直框中。 ```cs HBox hbox = new HBox(true, 3); ... Button ok = new Button("OK"); ok.SetSizeRequest(70, 30); Button close = new Button("Close"); hbox.Add(ok); hbox.Add(close); ``` 我们创建一个水平框,并在其中放置两个按钮。 ```cs Alignment halign = new Alignment(1, 0, 0, 0); halign.Add(hbox); vbox.PackStart(halign, false, false, 3); ``` 这将创建一个对齐容器,它将其子窗口小部件放在右侧。 我们将水平框添加到对齐容器中,然后将对齐容器包装到垂直框中。 我们必须记住,对齐容器仅包含一个子窗口小部件。 这就是为什么我们必须使用盒子。 ![Alignment](https://img.kancloud.cn/7f/db/7fdb8fcf675a39b8393870114e5b8d84_268x178.jpg) 图:对齐 ## `Table` `Table`小部件按行和列排列小部件。 `calculator.cs` ```cs using Gtk; using System; class SharpApp : Window { public SharpApp() : base("Calculator") { SetDefaultSize(250, 230); SetPosition(WindowPosition.Center); DeleteEvent += delegate { Application.Quit(); }; VBox vbox = new VBox(false, 2); MenuBar mb = new MenuBar(); Menu filemenu = new Menu(); MenuItem file = new MenuItem("File"); file.Submenu = filemenu; mb.Append(file); vbox.PackStart(mb, false, false, 0); Table table = new Table(5, 4, true); table.Attach(new Button("Cls"), 0, 1, 0, 1); table.Attach(new Button("Bck"), 1, 2, 0, 1); table.Attach(new Label(), 2, 3, 0, 1); table.Attach(new Button("Close"), 3, 4, 0, 1); table.Attach(new Button("7"), 0, 1, 1, 2); table.Attach(new Button("8"), 1, 2, 1, 2); table.Attach(new Button("9"), 2, 3, 1, 2); table.Attach(new Button("/"), 3, 4, 1, 2); table.Attach(new Button("4"), 0, 1, 2, 3); table.Attach(new Button("5"), 1, 2, 2, 3); table.Attach(new Button("6"), 2, 3, 2, 3); table.Attach(new Button("*"), 3, 4, 2, 3); table.Attach(new Button("1"), 0, 1, 3, 4); table.Attach(new Button("2"), 1, 2, 3, 4); table.Attach(new Button("3"), 2, 3, 3, 4); table.Attach(new Button("-"), 3, 4, 3, 4); table.Attach(new Button("0"), 0, 1, 4, 5); table.Attach(new Button("."), 1, 2, 4, 5); table.Attach(new Button("="), 2, 3, 4, 5); table.Attach(new Button("+"), 3, 4, 4, 5); vbox.PackStart(new Entry(), false, false, 0); vbox.PackEnd(table, true, true, 0); Add(vbox); ShowAll(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } } ``` 我们使用`Table`小部件创建一个计算器框架。 ```cs Table table = new Table(5, 4, true); ``` 我们创建一个具有 5 行 4 列的表小部件。 第三个参数是齐次参数。 如果设置为`true`,则表中的所有小部件都具有相同的大小。 所有窗口小部件的大小等于表容器中最大的窗口小部件。 ```cs table.Attach(new Button("Cls"), 0, 1, 0, 1); ``` 我们在表格容器上附加一个按钮。 到表格的左上方单元格。 前两个参数是单元格的左侧和右侧,后两个参数是单元格的顶部和左侧。 ```cs vbox.PackEnd(table, true, true, 0); ``` 我们将表格小部件打包到垂直框中。 ![Calculator skeleton](https://img.kancloud.cn/f3/b4/f3b4e531bcca2399111d89dd118ab7ab_258x258.jpg) 图:计算机骨架 ## 窗口 接下来,我们将创建一个更高级的示例。 我们显示一个窗口,可以在 JDeveloper IDE 中找到它。 `windows.cs` ```cs using Gtk; using System; class SharpApp : Window { public SharpApp() : base("Windows") { SetDefaultSize(300, 250); SetPosition(WindowPosition.Center); BorderWidth = 15; DeleteEvent += delegate { Application.Quit(); }; Table table = new Table(8, 4, false); table.ColumnSpacing = 3; Label title = new Label("Windows"); Alignment halign = new Alignment(0, 0, 0, 0); halign.Add(title); table.Attach(halign, 0, 1, 0, 1, AttachOptions.Fill, AttachOptions.Fill, 0, 0); TextView wins = new TextView(); wins.ModifyFg(StateType.Normal, new Gdk.Color(20, 20, 20)); wins.CursorVisible = false; table.Attach(wins, 0, 2, 1, 3, AttachOptions.Fill | AttachOptions.Expand, AttachOptions.Fill | AttachOptions.Expand, 1, 1); Button activate = new Button("Activate"); activate.SetSizeRequest(50, 30); table.Attach(activate, 3, 4, 1, 2, AttachOptions.Fill, AttachOptions.Shrink, 1, 1); Alignment valign = new Alignment(0, 0, 0, 0); Button close = new Button("Close"); close.SetSizeRequest(70, 30); valign.Add(close); table.SetRowSpacing(1, 3); table.Attach(valign, 3, 4, 2, 3, AttachOptions.Fill, AttachOptions.Fill | AttachOptions.Expand, 1, 1); Alignment halign2 = new Alignment(0, 1, 0, 0); Button help = new Button("Help"); help.SetSizeRequest(70, 30); halign2.Add(help); table.SetRowSpacing(3, 6); table.Attach(halign2, 0, 1, 4, 5, AttachOptions.Fill, AttachOptions.Fill, 0, 0); Button ok = new Button("OK"); ok.SetSizeRequest(70, 30); table.Attach(ok, 3, 4, 4, 5, AttachOptions.Fill, AttachOptions.Fill, 0, 0); Add(table); ShowAll(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } } ``` 该代码示例显示了如何在 GTK# 中创建类似的窗口。 ```cs Table table = new Table(8, 4, false); table.ColumnSpacing = 3; ``` 该示例基于`Table`容器。 列之间将有 3px 的间距。 ```cs Label title = new Label("Windows"); Alignment halign = new Alignment(0, 0, 0, 0); halign.Add(title); table.Attach(halign, 0, 1, 0, 1, AttachOptions.Fill, AttachOptions.Fill, 0, 0); ``` 这段代码创建了一个向左对齐的标签。 标签放置在`Table`容器的第一行中。 ```cs TextView wins = new TextView(); wins.ModifyFg(StateType.Normal, new Gdk.Color(20, 20, 20)); wins.CursorVisible = false; table.Attach(wins, 0, 2, 1, 3, AttachOptions.Fill | AttachOptions.Expand, AttachOptions.Fill | AttachOptions.Expand, 1, 1); ``` 文本视图小部件跨越两行两列。 我们使小部件不可编辑并隐藏光标。 ```cs Alignment valign = new Alignment(0, 0, 0, 0); Button close = new Button("Close"); close.SetSizeRequest(70, 30); valign.Add(close); table.SetRowSpacing(1, 3); table.Attach(valign, 3, 4, 2, 3, AttachOptions.Fill, AttachOptions.Fill | AttachOptions.Expand, 1, 1); ``` 我们将关闭按钮放在文本视图小部件旁边的第四列中。 (我们从零开始计数)将按钮添加到对齐小部件中,以便可以将其对齐到顶部。 ![Windows](https://img.kancloud.cn/28/82/2882f5030b0b821bb79ced8c120a67be_308x278.jpg) 图:窗口 在本章中,我们介绍了 GTK# 小部件的布局管理。