原文: http://zetcode.com/gui/pygtk/layout/

在 PyGTK 教程的这一章中,我们将展示如何在窗口或对话框中布置窗口小部件。

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

Fixed

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

fixed.py

  1. #!/usr/bin/python
  2. # ZetCode PyGTK tutorial
  3. #
  4. # This example demonstrates a Fixed
  5. # container widget
  6. #
  7. # author: jan bodnar
  8. # website: zetcode.com
  9. # last edited: February 2009
  10. import gtk
  11. import sys
  12. class PyApp(gtk.Window):
  13. def __init__(self):
  14. super(PyApp, self).__init__()
  15. self.set_title("Fixed")
  16. self.set_size_request(300, 280)
  17. self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(6400, 6400, 6440))
  18. self.set_position(gtk.WIN_POS_CENTER)
  19. try:
  20. self.bardejov = gtk.gdk.pixbuf_new_from_file("bardejov.jpg")
  21. self.rotunda = gtk.gdk.pixbuf_new_from_file("rotunda.jpg")
  22. self.mincol = gtk.gdk.pixbuf_new_from_file("mincol.jpg")
  23. except Exception, e:
  24. print e.message
  25. sys.exit(1)
  26. image1 = gtk.Image()
  27. image2 = gtk.Image()
  28. image3 = gtk.Image()
  29. image1.set_from_pixbuf(self.bardejov)
  30. image2.set_from_pixbuf(self.rotunda)
  31. image3.set_from_pixbuf(self.mincol)
  32. fix = gtk.Fixed()
  33. fix.put(image1, 20, 20)
  34. fix.put(image2, 40, 160)
  35. fix.put(image3, 170, 50)
  36. self.add(fix)
  37. self.connect("destroy", gtk.main_quit)
  38. self.show_all()
  39. PyApp()
  40. gtk.main()

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

  1. self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(6400, 6400, 6440))

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

  1. self.bardejov = gtk.gdk.pixbuf_new_from_file("bardejov.jpg")

我们从磁盘上的文件加载映像。

  1. image1 = gtk.Image()
  2. image2 = gtk.Image()
  3. image3 = gtk.Image()
  4. image1.set_from_pixbuf(self.bardejov)
  5. image2.set_from_pixbuf(self.rotunda)
  6. image3.set_from_pixbuf(self.mincol)

Image是用于显示图像的小部件。 它在构造器中使用一个Pixbuf对象。

  1. fix = gtk.Fixed()

我们创建Fixed容器。

  1. fix.put(image1, 20, 20)

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

  1. self.add(fix)

最后,我们将Fixed容器添加到窗口中。

PyGTK 中的布局管理 - 图1

图:固定

Alignment

Alignment容器控制其子窗口小部件的对齐方式和大小。

alignment.py

  1. #!/usr/bin/python
  2. # ZetCode PyGTK tutorial
  3. #
  4. # This example shows how to use
  5. # the Alignment widget
  6. #
  7. # author: jan bodnar
  8. # website: zetcode.com
  9. # last edited: February 2009
  10. import gtk
  11. class PyApp(gtk.Window):
  12. def __init__(self):
  13. super(PyApp, self).__init__()
  14. self.set_title("Alignment")
  15. self.set_size_request(260, 150)
  16. self.set_position(gtk.WIN_POS_CENTER)
  17. vbox = gtk.VBox(False, 5)
  18. hbox = gtk.HBox(True, 3)
  19. valign = gtk.Alignment(0, 1, 0, 0)
  20. vbox.pack_start(valign)
  21. ok = gtk.Button("OK")
  22. ok.set_size_request(70, 30)
  23. close = gtk.Button("Close")
  24. hbox.add(ok)
  25. hbox.add(close)
  26. halign = gtk.Alignment(1, 0, 0, 0)
  27. halign.add(hbox)
  28. vbox.pack_start(halign, False, False, 3)
  29. self.add(vbox)
  30. self.connect("destroy", gtk.main_quit)
  31. self.show_all()
  32. PyApp()
  33. gtk.main()

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

  1. valign = gtk.Alignment(0, 1, 0, 0)

这会将子窗口小部件置于底部。

  1. vbox.pack_start(valign)

在这里,我们将Alignment小部件放置到垂直框中。

  1. hbox = gtk.HBox(True, 3)
  2. ...
  3. ok = gtk.Button("OK")
  4. ok.set_size_request(70, 30)
  5. close = gtk.Button("Close")
  6. hbox.add(ok)
  7. hbox.add(close)

我们创建一个水平框,并在其中放置两个按钮。

  1. halign = gtk.Alignment(1, 0, 0, 0)
  2. halign.add(hbox)
  3. vbox.pack_start(halign, False, False, 3)

这将创建一个对齐容器,它将其子窗口小部件放在右侧。 我们将水平框添加到对齐容器中,然后将对齐容器包装到垂直框中。 我们必须记住,对齐容器仅包含一个子窗口小部件。 这就是为什么我们必须使用盒子。

PyGTK 中的布局管理 - 图2

图:对齐

Table

Table小部件按行和列排列小部件。

calculator.py

  1. #!/usr/bin/python
  2. # ZetCode PyGTK tutorial
  3. #
  4. # This example shows how to use
  5. # the Table container widget
  6. #
  7. # author: jan bodnar
  8. # website: zetcode.com
  9. # last edited: February 2009
  10. import gtk
  11. class PyApp(gtk.Window):
  12. def __init__(self):
  13. super(PyApp, self).__init__()
  14. self.set_title("Calculator")
  15. self.set_size_request(250, 230)
  16. self.set_position(gtk.WIN_POS_CENTER)
  17. vbox = gtk.VBox(False, 2)
  18. mb = gtk.MenuBar()
  19. filemenu = gtk.Menu()
  20. filem = gtk.MenuItem("File")
  21. filem.set_submenu(filemenu)
  22. mb.append(filem)
  23. vbox.pack_start(mb, False, False, 0)
  24. table = gtk.Table(5, 4, True)
  25. table.attach(gtk.Button("Cls"), 0, 1, 0, 1)
  26. table.attach(gtk.Button("Bck"), 1, 2, 0, 1)
  27. table.attach(gtk.Label(), 2, 3, 0, 1)
  28. table.attach(gtk.Button("Close"), 3, 4, 0, 1)
  29. table.attach(gtk.Button("7"), 0, 1, 1, 2)
  30. table.attach(gtk.Button("8"), 1, 2, 1, 2)
  31. table.attach(gtk.Button("9"), 2, 3, 1, 2)
  32. table.attach(gtk.Button("/"), 3, 4, 1, 2)
  33. table.attach(gtk.Button("4"), 0, 1, 2, 3)
  34. table.attach(gtk.Button("5"), 1, 2, 2, 3)
  35. table.attach(gtk.Button("6"), 2, 3, 2, 3)
  36. table.attach(gtk.Button("*"), 3, 4, 2, 3)
  37. table.attach(gtk.Button("1"), 0, 1, 3, 4)
  38. table.attach(gtk.Button("2"), 1, 2, 3, 4)
  39. table.attach(gtk.Button("3"), 2, 3, 3, 4)
  40. table.attach(gtk.Button("-"), 3, 4, 3, 4)
  41. table.attach(gtk.Button("0"), 0, 1, 4, 5)
  42. table.attach(gtk.Button("."), 1, 2, 4, 5)
  43. table.attach(gtk.Button("="), 2, 3, 4, 5)
  44. table.attach(gtk.Button("+"), 3, 4, 4, 5)
  45. vbox.pack_start(gtk.Entry(), False, False, 0)
  46. vbox.pack_end(table, True, True, 0)
  47. self.add(vbox)
  48. self.connect("destroy", gtk.main_quit)
  49. self.show_all()
  50. PyApp()
  51. gtk.main()

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

  1. table = gtk.Table(5, 4, True)

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

  1. table.attach(gtk.Button("Cls"), 0, 1, 0, 1)

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

  1. vbox.pack_end(table, True, True, 0)

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

PyGTK 中的布局管理 - 图3

图:计算机骨架

窗口

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

windows.py

  1. #!/usr/bin/python
  2. # ZetCode PyGTK tutorial
  3. #
  4. # This is a more complicated layout
  5. # example
  6. #
  7. # author: jan bodnar
  8. # website: zetcode.com
  9. # last edited: February 2009
  10. import gtk
  11. import sys
  12. class PyApp(gtk.Window):
  13. def __init__(self):
  14. super(PyApp, self).__init__()
  15. self.set_title("Windows")
  16. self.set_size_request(300, 250)
  17. self.set_border_width(8)
  18. self.set_position(gtk.WIN_POS_CENTER)
  19. table = gtk.Table(8, 4, False)
  20. table.set_col_spacings(3)
  21. title = gtk.Label("Windows")
  22. halign = gtk.Alignment(0, 0, 0, 0)
  23. halign.add(title)
  24. table.attach(halign, 0, 1, 0, 1, gtk.FILL,
  25. gtk.FILL, 0, 0);
  26. wins = gtk.TextView()
  27. wins.set_editable(False)
  28. wins.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(5140, 5140, 5140))
  29. wins.set_cursor_visible(False)
  30. table.attach(wins, 0, 2, 1, 3, gtk.FILL | gtk.EXPAND,
  31. gtk.FILL | gtk.EXPAND, 1, 1)
  32. activate = gtk.Button("Activate")
  33. activate.set_size_request(50, 30)
  34. table.attach(activate, 3, 4, 1, 2, gtk.FILL,
  35. gtk.SHRINK, 1, 1)
  36. valign = gtk.Alignment(0, 0, 0, 0)
  37. close = gtk.Button("Close")
  38. close.set_size_request(70, 30)
  39. valign.add(close)
  40. table.set_row_spacing(1, 3)
  41. table.attach(valign, 3, 4, 2, 3, gtk.FILL,
  42. gtk.FILL | gtk.EXPAND, 1, 1)
  43. halign2 = gtk.Alignment(0, 1, 0, 0)
  44. help = gtk.Button("Help")
  45. help.set_size_request(70, 30)
  46. halign2.add(help)
  47. table.set_row_spacing(3, 6)
  48. table.attach(halign2, 0, 1, 4, 5, gtk.FILL,
  49. gtk.FILL, 0, 0)
  50. ok = gtk.Button("OK")
  51. ok.set_size_request(70, 30)
  52. table.attach(ok, 3, 4, 4, 5, gtk.FILL,
  53. gtk.FILL, 0, 0);
  54. self.add(table)
  55. self.connect("destroy", gtk.main_quit)
  56. self.show_all()
  57. PyApp()
  58. gtk.main()

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

  1. table = gtk.Table(8, 4, False)
  2. table.set_col_spacings(3)

该示例基于Table容器。 列之间将有 3px 的间距。

  1. title = gtk.Label("Windows")
  2. halign = gtk.Alignment(0, 0, 0, 0)
  3. halign.add(title)
  4. table.attach(halign, 0, 1, 0, 1, gtk.FILL,
  5. gtk.FILL, 0, 0);

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

  1. wins = gtk.TextView()
  2. wins.set_editable(False)
  3. wins.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(5140, 5140, 5140))
  4. wins.set_cursor_visible(False)
  5. table.attach(wins, 0, 2, 1, 3, gtk.FILL | gtk.EXPAND,
  6. gtk.FILL | gtk.EXPAND, 1, 1)

文本视图小部件跨越两行两列。 我们使小部件不可编辑并隐藏光标。

  1. valign = gtk.Alignment(0, 0, 0, 0)
  2. close = gtk.Button("Close")
  3. close.set_size_request(70, 30)
  4. valign.add(close)
  5. table.set_row_spacing(1, 3)
  6. table.attach(valign, 3, 4, 2, 3, gtk.FILL,
  7. gtk.FILL | gtk.EXPAND, 1, 1)

我们将关闭按钮放在文本视图小部件旁边的第四列中。 (我们从零开始计数)将按钮添加到对齐小部件中,以便可以将其对齐到顶部。

PyGTK 中的布局管理 - 图4

图:窗口

PyGTK 编程教程的这一章是有关布局管理的。