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

在 Tcl/Tk 编程教程的这一部分中,我们将介绍布局管理器。

在设计应用的 GUI 时,我们决定要使用哪些小部件以及如何在应用中组织这些小部件。 为了组织小部件,我们使用专门的不可见对象,称为布局管理器。

有两种小部件:容器及其子级。 容器将子项分组为合适的布局。

Tk 具有三个内置布局管理器:packgridplace管理器。 包几何形状管理器在垂直和水平框中组织小部件。 网格几何管理器将小部件放置在二维网格中。 最后,place几何管理器使用绝对定位将小部件放置在其容器上。

绝对定位

在大多数情况下,程序员应使用布局管理器。 在某些情况下,我们可以使用绝对定位。 在绝对定位中,程序员以像素为单位指定每个小部件的位置和大小。 如果我们调整窗口大小,则小部件的大小和位置不会改变。 在各种平台上,应用看起来都不同,在 Linux 上看起来不错,在 Mac OS 上看起来不太正常。 在我们的应用中更改字体可能会破坏布局。 如果我们将应用翻译成另一种语言,则必须重做您的布局。

  1. #!/usr/bin/wish
  2. # ZetCode Tcl/Tk tutorial
  3. #
  4. # In this script, we lay out images
  5. # using absolute positioning.
  6. #
  7. # author: Jan Bodnar
  8. # last modified: March 2011
  9. # website: www.zetcode.com
  10. package require Img
  11. frame .fr -background "#333"
  12. pack .fr -fill both -expand 1
  13. image create photo img1 -file "bardejov.jpg"
  14. label .fr.lbl1 -image img1
  15. place .fr.lbl1 -x 20 -y 20
  16. image create photo img2 -file "rotunda.jpg"
  17. label .fr.lbl2 -image img2
  18. place .fr.lbl2 -x 40 -y 160
  19. image create photo img3 -file "mincol.jpg"
  20. label .fr.lbl3 -image img3
  21. place .fr.lbl3 -x 170 -y 50
  22. wm title . "absolute"
  23. wm geometry . 300x280+300+300

在此示例中,我们使用绝对定位放置了三个图像。 我们将使用位置几何图形管理器。

  1. package require Img

我们使用Img包来显示 JPG 图像。 在 Ubuntu Linux 上,我们必须安装libtk-img包。

  1. package require Img

要显示 JPG 图像,我们使用Img包。

  1. frame .fr -background "#333"

我们的框架将具有深灰色背景。

  1. image create photo img1 -file "bardejov.jpg"

我们从当前工作目录中的图像创建照片图像对象。

  1. label .fr.lbl1 -image img1

我们用图像创建一个label。 标签可以包含文本或图像。

  1. place .fr.lbl1 -x 20 -y 20

标签放置在框架上的x = 20y = 20坐标处。 绝对定位通过place命令完成。

Tcl/Tk 中的布局管理 - 图1

图:绝对定位

按钮示例

在下面的示例中,我们将在窗口的右下角放置两个按钮。 我们将使用pack管理器。

  1. #!/usr/bin/wish
  2. # ZetCode Tcl/Tk tutorial
  3. #
  4. # In this script, we use pack manager
  5. # to position two buttons in the
  6. # bottom right corner of the window.
  7. #
  8. # author: Jan Bodnar
  9. # last modified: March 2011
  10. # website: www.zetcode.com
  11. frame .fr
  12. pack .fr -fill both -expand 1
  13. frame .fr.pnl -relief raised -borderwidth 1
  14. pack .fr.pnl -fill both -expand 1
  15. ttk::button .fr.cb -text "Close"
  16. pack .fr.cb -padx 5 -pady 5 -side right
  17. ttk::button .fr.ok -text "OK"
  18. pack .fr.ok -side right
  19. wm title . "buttons"
  20. wm geometry . 300x200+300+300

我们将有两个框架。 有一个基础框架和一个附加框架,该框架将在两个方向上扩展并将两个按钮按到基础框架的底部。 这些按钮放置在水平框中,并位于此框的右侧。

  1. frame .fr.pnl -relief raised -borderwidth 1
  2. pack .fr.pnl -fill both -expand 1

我们创建另一个frame小部件。 该小部件占用了大部分区域。 我们更改框架的边框,以使框架可见。 默认情况下,它是平坦的。 pack管理器在两个方向上扩展框架。 水平和垂直。

  1. ttk::button .fr.cb -text "Close"
  2. pack .fr.cb -padx 5 -pady 5 -side right

创建一个关闭按钮。 将其放入水平盒中。 -side选项将创建一个水平框布局,其中按钮位于框的右侧。 -padx-pady选项将在小部件之间放置一些空间。 -padx在按钮小部件之间以及关闭按钮和根窗口的右边框之间放置一些空间。 -pady在按钮小部件与框架和根窗口的边框之间放置一些空间。

  1. pack .fr.ok -side right

ok按钮位于关闭按钮旁边。 它们之间有 5px 的间距。

Tcl/Tk 中的布局管理 - 图2

图:按钮示例

计算器

我们将使用 Tk 网格几何管理器来创建计算器的骨架。

  1. #!/usr/bin/wish
  2. # ZetCode Tcl/Tk tutorial
  3. #
  4. # In this script, we use the grid manager
  5. # to create a skeleton of a calculator.
  6. #
  7. # author: Jan Bodnar
  8. # last modified: March 2011
  9. # website: www.zetcode.com
  10. frame .fr -padx 5 -pady 5
  11. pack .fr -fill both -expand 1
  12. ttk::style configure TButton -width 8 -height 8 -font "serif 10"
  13. entry .fr.ent
  14. grid .fr.ent -row 0 -columnspan 4 -sticky we
  15. ttk::button .fr.cls -text "Cls"
  16. grid .fr.cls -row 1 -column 0
  17. ttk::button .fr.bck -text "Back"
  18. grid .fr.bck -row 1 -column 1
  19. ttk::button .fr.lbl
  20. grid .fr.lbl -row 1 -column 2
  21. ttk::button .fr.clo -text "Close"
  22. grid .fr.clo -row 1 -column 3
  23. ttk::button .fr.sev -text "7"
  24. grid .fr.sev -row 2 -column 0
  25. ttk::button .fr.eig -text "8"
  26. grid .fr.eig -row 2 -column 1
  27. ttk::button .fr.nin -text "9"
  28. grid .fr.nin -row 2 -column 2
  29. ttk::button .fr.div -text "/"
  30. grid .fr.div -row 2 -column 3
  31. ttk::button .fr.fou -text "4"
  32. grid .fr.fou -row 3 -column 0
  33. ttk::button .fr.fiv -text "5"
  34. grid .fr.fiv -row 3 -column 1
  35. ttk::button .fr.six -text "6"
  36. grid .fr.six -row 3 -column 2
  37. ttk::button .fr.mul -text "*"
  38. grid .fr.mul -row 3 -column 3
  39. ttk::button .fr.one -text "1"
  40. grid .fr.one -row 4 -column 0
  41. ttk::button .fr.two -text "2"
  42. grid .fr.two -row 4 -column 1
  43. ttk::button .fr.thr -text "3"
  44. grid .fr.thr -row 4 -column 2
  45. ttk::button .fr.mns -text "-"
  46. grid .fr.mns -row 4 -column 3
  47. ttk::button .fr.zer -text "0"
  48. grid .fr.zer -row 5 -column 0
  49. ttk::button .fr.dot -text "."
  50. grid .fr.dot -row 5 -column 1
  51. ttk::button .fr.equ -text "="
  52. grid .fr.equ -row 5 -column 2
  53. ttk::button .fr.pls -text "+"
  54. grid .fr.pls -row 5 -column 3
  55. grid columnconfigure .fr 0 -pad 3
  56. grid columnconfigure .fr 1 -pad 3
  57. grid columnconfigure .fr 2 -pad 3
  58. grid columnconfigure .fr 3 -pad 3
  59. grid rowconfigure .fr 0 -pad 3
  60. grid rowconfigure .fr 1 -pad 3
  61. grid rowconfigure .fr 2 -pad 3
  62. grid rowconfigure .fr 3 -pad 3
  63. grid rowconfigure .fr 4 -pad 3
  64. wm title . "calculator"
  65. wm geometry . +300+300

在此示例中,我们使用grid管理器来组织框架容器小部件中的按钮。

  1. ttk::style configure TButton -width 8 -height 8 -font "serif 10"

我们将主题button小部件配置为具有特定字体并具有一些内部填充。

  1. entry .fr.ent
  2. grid .fr.ent -row 0 -columnspan 4 -sticky we

entry小部件是显示数字的地方。 小部件位于第一行,它将覆盖所有四列。 小部件可能不会占用网格中单元所分配的所有空间。 -sticky选项将沿给定方向扩展小部件。 在我们的案例中,我们确保条目小部件从左向右展开。

  1. ttk::button .fr.cls -text "Cls"

cls按钮位于第二行和第一列。 请注意,行和列从零开始。 ttk::button是一个主题按钮。

  1. grid columnconfigure .fr 0 -pad 3
  2. ...
  3. grid rowconfigure .fr 0 -pad 3

我们使用columnconfigurerowconfigure命令在网格列和行中定义一些空间。 这样,我们可以实现按钮之间有一定的间隔。

Tcl/Tk 中的布局管理 - 图3

图:计算器

Windows 示例

以下示例使用网格几何管理器创建 Windows 对话框。 该对话框来自 JDeveloper 应用。

  1. #!/usr/bin/wish
  2. # ZetCode Tcl/Tk tutorial
  3. #
  4. # In this script, we use the grid
  5. # manager to create a more complicated
  6. # layout.
  7. #
  8. # author: Jan Bodnar
  9. # last modified: March 2011
  10. # website: www.zetcode.com
  11. frame .fr -padx 5 -pady 5
  12. pack .fr -fill both -expand 1
  13. label .fr.lbl -text Windows
  14. grid .fr.lbl -sticky w -pady 4 -padx 5
  15. text .fr.area
  16. grid .fr.area -row 1 -column 0 -columnspan 2 \
  17. -rowspan 4 -padx 5 -sticky ewsn
  18. ttk::button .fr.act -text Activate
  19. grid .fr.act -row 1 -column 3
  20. ttk::button .fr.cls -text Close
  21. grid .fr.cls -row 2 -column 3 -pady 4
  22. ttk::button .fr.hlp -text Help
  23. grid .fr.hlp -row 5 -column 0 -padx 5
  24. ttk::button .fr.ok -text OK
  25. grid .fr.ok -row 5 -column 3
  26. grid columnconfigure .fr 1 -weight 1
  27. grid columnconfigure .fr 3 -pad 7
  28. grid rowconfigure .fr 3 -weight 1
  29. grid rowconfigure .fr 5 -pad 7
  30. wm title . "Windows"
  31. wm geometry . 350x300+300+300

在此示例中,我们将使用label小部件,text小部件和四个按钮。

  1. label .fr.lbl -text Windows
  2. grid .fr.lbl -sticky w -pady 4 -padx 5

标签窗口小部件已创建并放入网格中。 如果未指定列和行,则假定为第一列或行。 该标签向西粘贴,并且其文本周围有一些填充。

  1. text .fr.area
  2. grid .fr.area -row 1 -column 0 -columnspan 2 \
  3. -rowspan 4 -padx 5 -sticky ewsn

text小部件已创建,并从第二行第一列开始。 它跨越2列和4行。 小部件和根窗口的左边界之间有 4px 空间。 最后,它坚持所有四个方面。 因此,调整窗口大小时,text小部件会向各个方向扩展。

  1. grid columnconfigure .fr 1 -weight 1
  2. grid columnconfigure .fr 3 -pad 7
  3. grid rowconfigure .fr 3 -weight 1
  4. grid rowconfigure .fr 5 -pad 7

我们在网格中的小部件之间定义一些空间。 在text小部件和按钮之间放置最大的空间。

Tcl/Tk 中的布局管理 - 图4

图:窗口示例

在 Tcl/Tk 教程的这一部分中,我们提到了小部件的布局管理。