原文: http://zetcode.com/gui/rubyqt/layoutmanagement/

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

在设计应用的 GUI 时,我们决定要使用哪些组件以及如何在应用中组织这些组件。 为了组织我们的组件,我们使用专门的不可见对象,称为布局管理器。 Qt 中有几个选项。 我们可以使用绝对定位,内置布局管理器或创建自定义布局管理器。 我们还可以使用 Qt Designer 直观地构建布局。

Qt 有一些重要的内置布局管理器。 Qt::VBoxLayout类垂直排列小部件。 Qt::HBoxLayout水平排列小部件。 Qt::GridLayout类将小部件布置在网格中。 网格布局是最灵活的布局管理器。 框布局可以相互嵌套以创建复杂的布局。

绝对定位

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

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # In this program, we lay out widgets
  5. # using absolute positioning.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: September 2012
  10. require 'Qt'
  11. class QtApp < Qt::Widget
  12. def initialize
  13. super
  14. setWindowTitle "Absolute"
  15. init_ui
  16. resize 300, 280
  17. move 300, 300
  18. show
  19. end
  20. def init_ui
  21. setStyleSheet "QWidget { background-color: #414141 }"
  22. bardejov = Qt::Pixmap.new "bardejov.jpg"
  23. rotunda = Qt::Pixmap.new "rotunda.jpg"
  24. mincol = Qt::Pixmap.new "mincol.jpg"
  25. barLabel = Qt::Label.new self
  26. barLabel.setPixmap bardejov
  27. barLabel.move 20, 20
  28. rotLabel = Qt::Label.new self
  29. rotLabel.setPixmap rotunda
  30. rotLabel.move 40, 160
  31. minLabel = Qt::Label.new self
  32. minLabel.setPixmap mincol
  33. minLabel.move 170, 50
  34. end
  35. end
  36. app = Qt::Application.new ARGV
  37. QtApp.new
  38. app.exec

在此示例中,我们使用绝对定位显示了三幅图像。

  1. barLabel = Qt::Label.new self
  2. barLabel.setPixmap bardejov

Qt::Label小部件用于保存图像。

  1. barLabel.move 20, 20

我们使用move方法将标签放置在窗口上的x = 20y = 20处。

调整窗口大小时,标签将保留其初始大小。

Ruby Qt 中的布局管理 - 图1

图:绝对定位

按钮示例

在下面的示例中,我们将在窗口的右下角放置两个按钮。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # In this program, we use box layouts
  5. # to position two buttons in the
  6. # bottom right corner of the window.
  7. #
  8. # author: Jan Bodnar
  9. # website: www.zetcode.com
  10. # last modified: September 2012
  11. require 'Qt'
  12. class QtApp < Qt::Widget
  13. def initialize
  14. super
  15. setWindowTitle "Buttons"
  16. init_ui
  17. resize 330, 170
  18. move 300, 300
  19. show
  20. end
  21. def init_ui
  22. vbox = Qt::VBoxLayout.new self
  23. hbox = Qt::HBoxLayout.new
  24. ok = Qt::PushButton.new "OK", self
  25. apply = Qt::PushButton.new "Apply", self
  26. hbox.addWidget ok, 1, Qt::AlignRight
  27. hbox.addWidget apply
  28. vbox.addStretch 1
  29. vbox.addLayout hbox
  30. end
  31. end
  32. app = Qt::Application.new ARGV
  33. QtApp.new
  34. app.exec

我们使用嵌套框布局来获得我们想要的布局。

  1. vbox = Qt::VBoxLayout.new self
  2. hbox = Qt::HBoxLayout.new

我们使用一个垂直框和一个水平框。

  1. ok = Qt::PushButton.new "OK", self
  2. apply = Qt::PushButton.new "Apply", self

这是两个将进入窗口右下角的按钮。

  1. hbox.addWidget ok, 1, Qt::AlignRight

我们将确定按钮放入水平框中。 第二个参数是stretch因子。 它将扩大分配给“确定”按钮的区域。 它会占用所有可用空间。 该区域内小风口的对齐方式由第三个参数控制。 Qt::AlignRight将按钮向右对齐。

  1. vbox.addStretch 1

这条线创建了一个垂直扩展的白色空间,它将带有按钮的水平框推到底部。

  1. vbox.addLayout hbox

水平框嵌套在垂直框中。

Ruby Qt 中的布局管理 - 图2

图:按钮示例

Windows 示例

以下是嵌套框布局更复杂的示例。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # In this program, use box layouts
  5. # to create a Windows example
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: September 2012
  10. require 'Qt'
  11. class QtApp < Qt::Widget
  12. def initialize
  13. super
  14. setWindowTitle "Windows"
  15. init_ui
  16. resize 350, 300
  17. move 300, 300
  18. show
  19. end
  20. def init_ui
  21. vbox = Qt::VBoxLayout.new self
  22. vbox1 = Qt::VBoxLayout.new
  23. hbox1 = Qt::HBoxLayout.new
  24. hbox2 = Qt::HBoxLayout.new
  25. windLabel = Qt::Label.new "Windows", self
  26. edit = Qt::TextEdit.new self
  27. edit.setEnabled false
  28. activate = Qt::PushButton.new "Activate", self
  29. close = Qt::PushButton.new "Close", self
  30. help = Qt::PushButton.new "Help", self
  31. ok = Qt::PushButton.new "OK", self
  32. vbox.addWidget windLabel
  33. vbox1.addWidget activate
  34. vbox1.addWidget close, 0, Qt::AlignTop
  35. hbox1.addWidget edit
  36. hbox1.addLayout vbox1
  37. vbox.addLayout hbox1
  38. hbox2.addWidget help
  39. hbox2.addStretch 1
  40. hbox2.addWidget ok
  41. vbox.addLayout hbox2, 1
  42. setLayout vbox
  43. end
  44. end
  45. app = Qt::Application.new ARGV
  46. QtApp.new
  47. app.exec

在此布局中,我们使用两个垂直和水平框。

  1. box = Qt::VBoxLayout.new self

这是示例的基本布局。

  1. windLabel = Qt::Label.new "Windows", self

首先是标签小部件。 它只是转到垂直框的顶部。

  1. vbox1.addWidget activate
  2. vbox1.addWidget close, 0, Qt::AlignTop
  3. hbox1.addWidget edit
  4. hbox1.addLayout vbox1
  5. vbox.addLayout hbox1

在窗口的中心部分,我们有一个文本编辑小部件和两个垂直排列的按钮。 这些按钮进入垂直框。 在此垂直框中,按钮与顶部对齐。 垂直框和文本编辑进入水平框。 该水平框转到标签窗口小部件正下方的基本垂直框。

  1. hbox2.addWidget help
  2. hbox2.addStretch 1
  3. hbox2.addWidget ok
  4. vbox.addLayout hbox2, 1

帮助和确定按钮进入另一个水平框。 这两个按钮之间有一个扩大的空白区域。 同样,水平框转到基本垂直框。

  1. setLayout vbox

基本的垂直框设置为窗口的主要布局。

Ruby Qt 中的布局管理 - 图3

图:窗口示例

新文件夹示例

在最后一个示例中,我们使用Qt::GridLayout管理器创建“新文件夹”布局示例。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # In this program, use the GridLayout
  5. # to create a New Folder example.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: September 2012
  10. require 'Qt'
  11. class QtApp < Qt::Widget
  12. def initialize
  13. super
  14. setWindowTitle "New Folder"
  15. init_ui
  16. resize 300, 300
  17. move 300, 300
  18. show
  19. end
  20. def init_ui
  21. grid = Qt::GridLayout.new self
  22. nameLabel = Qt::Label.new "Name", self
  23. nameEdit = Qt::LineEdit.new self
  24. text = Qt::TextEdit.new self
  25. okButton = Qt::PushButton.new "OK", self
  26. closeButton = Qt::PushButton.new "Close", self
  27. grid.addWidget nameLabel, 0, 0
  28. grid.addWidget nameEdit, 0, 1, 1, 3
  29. grid.addWidget text, 1, 0, 2, 4
  30. grid.setColumnStretch 1, 1
  31. grid.addWidget okButton, 4, 2
  32. grid.addWidget closeButton, 4, 3
  33. end
  34. end
  35. app = Qt::Application.new(ARGV)
  36. QtApp.new
  37. app.exec

在我们的示例中,我们有一个标签,一行编辑,一个文本编辑和两个按钮。

  1. grid = Qt::GridLayout.new self

我们创建Qt::GridLayout管理器的实例。

  1. grid.addWidget nameLabel, 0, 0

我们将标签小部件放置在网格的第一个单元格中。 单元格从 0 开始计数。最后两个参数是行号和列号。

  1. grid.addWidget nameEdit, 0, 1, 1, 3

线编辑窗口小部件位于第一行第二列。 最后两个参数是行跨度和列跨度。 在水平方向上,小部件将跨越三列。

  1. grid.setColumnStretch 1, 1

该方法的参数是列号和拉伸因子。 在这里,我们将拉伸因子 1 设置到第二列。 这意味着此列将占用所有剩余空间。 之所以这样设置,是因为我们希望按钮保持其初始大小。

Ruby Qt 中的布局管理 - 图4

图:新文件夹 example

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