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

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

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

Qyoto 有一些重要的内置布局管理器。 QVBoxLayout类垂直排列小部件。 QHBoxLayout水平排列小部件。 QGridLayout类将小部件布置在网格中。 网格布局是最灵活的布局管理器。 盒子布局相互嵌套以创建复杂的布局。

绝对定位

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

  1. ' ZetCode Mono Visual Basic Qt tutorial
  2. '
  3. ' In this program, we lay out widgets
  4. ' using absolute positioning
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports Qyoto
  10. Public Class VBQApp
  11. Inherits QMainWindow
  12. Dim bardejov As QPixmap
  13. Dim rotunda As QPixmap
  14. Dim mincol As QPixmap
  15. Public Sub New()
  16. Me.SetWindowTitle("Absolute")
  17. Me.InitUI()
  18. Me.Resize(300, 280)
  19. Me.Move(300, 300)
  20. Me.Show()
  21. End Sub
  22. Private Sub InitUI()
  23. SetStyleSheet("QWidget { background-color: #414141 }")
  24. Try
  25. bardejov = New QPixmap("bardejov.jpg")
  26. rotunda = New QPixmap("rotunda.jpg")
  27. mincol = New QPixmap("mincol.jpg")
  28. Catch e As Exception
  29. Console.WriteLine(e.Message)
  30. Environment.Exit(1)
  31. End Try
  32. Dim barLabel As New QLabel(Me)
  33. barLabel.SetPixmap(bardejov)
  34. barLabel.SetGeometry(20, 20, 120, 90)
  35. Dim rotLabel As New QLabel(Me)
  36. rotLabel.SetPixmap(rotunda)
  37. rotLabel.SetGeometry(40, 160, 120, 90)
  38. Dim minLabel As New QLabel(Me)
  39. minLabel.SetPixmap(mincol)
  40. minLabel.SetGeometry(170, 50, 120, 90)
  41. End Sub
  42. Public Shared Sub Main(ByVal args() As String)
  43. Dim qapp As New QApplication(args)
  44. Dim app As New VBQApp
  45. QApplication.Exec()
  46. End Sub
  47. End Class

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

  1. Dim barLabel As New QLabel(Me)
  2. barLabel.SetPixmap(bardejov)

QLabel小部件用于保存图像。

  1. barLabel.SetGeometry(20, 20, 120, 90)

我们使用SetGeometry()方法将标签放置在窗口上的x = 20y = 20处。 图片大小为120x90

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

布局管理 - 图1

图:绝对定位

按钮示例

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

  1. ' ZetCode Mono Visual Basic Qt tutorial
  2. '
  3. ' In this program, use box layouts
  4. ' to position two buttons in the
  5. ' bottom right corner of the window
  6. '
  7. ' author jan bodnar
  8. ' last modified May 2009
  9. ' website www.zetcode.com
  10. Imports Qyoto
  11. Public Class VBQApp
  12. Inherits QWidget
  13. Public Sub New()
  14. Me.SetWindowTitle("Buttons")
  15. Me.InitUI()
  16. Me.Resize(300, 150)
  17. Me.Move(300, 300)
  18. Me.Show()
  19. End Sub
  20. Private Sub InitUI()
  21. Dim vbox As New QVBoxLayout(Me)
  22. Dim hbox As New QHBoxLayout
  23. Dim ok As New QPushButton("OK", Me)
  24. Dim apply As New QPushButton("Apply", Me)
  25. hbox.AddWidget(ok, 1, Qt.AlignmentFlag.AlignRight)
  26. hbox.AddWidget(apply)
  27. vbox.AddStretch(1)
  28. vbox.AddLayout(hbox)
  29. End Sub
  30. Public Shared Sub Main(ByVal args() As String)
  31. Dim qapp As New QApplication(args)
  32. Dim app As New VBQApp
  33. QApplication.Exec()
  34. End Sub
  35. End Class

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

  1. Dim vbox As New QVBoxLayout(Me)
  2. Dim hbox As New QHBoxLayout

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

  1. Dim ok As New QPushButton("OK", Me)
  2. Dim apply As New QPushButton("Apply", Me)

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

  1. hbox.AddWidget(ok, 1, Qt.AlignmentFlag.AlignRight)

我们将确定按钮放入水平框中。 第二个参数是stretch因子。 它将扩大分配给“确定”按钮的区域。 它会占用所有可用空间。 在此区域内,按钮向右对齐。

  1. vbox.AddStretch(1)

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

  1. vbox.AddLayout(hbox)

水平框嵌套在垂直框中。

布局管理 - 图2

图:按钮示例

Windows 示例

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

  1. ' ZetCode Mono Visual Basic Qt tutorial
  2. '
  3. ' In this program, use box layouts
  4. ' to create a windows example
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports Qyoto
  10. Public Class VBQApp
  11. Inherits QWidget
  12. Public Sub New()
  13. Me.SetWindowTitle("Windows")
  14. Me.InitUI()
  15. Me.Resize(350, 300)
  16. Me.Move(300, 300)
  17. Me.Show()
  18. End Sub
  19. Private Sub InitUI()
  20. Dim vbox As New QVBoxLayout(Me)
  21. Dim vbox1 As New QVBoxLayout
  22. Dim hbox1 As New QHBoxLayout
  23. Dim hbox2 As New QHBoxLayout
  24. Dim windLabel As New QLabel("Windows", Me)
  25. Dim edit As New QTextEdit(Me)
  26. edit.SetEnabled(False)
  27. Dim activate As New QPushButton("Activate", Me)
  28. Dim close As New QPushButton("Close", Me)
  29. Dim help As New QPushButton("Help", Me)
  30. Dim ok As New QPushButton("OK", Me)
  31. vbox.AddWidget(windLabel)
  32. vbox1.AddWidget(activate)
  33. vbox1.AddWidget(close, 0, AlignmentFlag.AlignTop)
  34. hbox1.AddWidget(edit)
  35. hbox1.AddLayout(vbox1)
  36. vbox.AddLayout(hbox1)
  37. hbox2.AddWidget(help)
  38. hbox2.AddStretch(1)
  39. hbox2.AddWidget(ok)
  40. vbox.AddLayout(hbox2, 1)
  41. End Sub
  42. Public Shared Sub Main(ByVal args() As String)
  43. Dim qapp As New QApplication(args)
  44. Dim app As New VBQApp
  45. QApplication.Exec()
  46. End Sub
  47. End Class

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

  1. Dim vbox As New QVBoxLayout(Me)

这是示例的基本布局。

  1. vbox.AddWidget(windLabel)

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

  1. vbox1.AddWidget(activate)
  2. vbox1.AddWidget(close, 0, AlignmentFlag.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)

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

布局管理 - 图3

图:窗口示例

新文件夹示例

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

  1. ' ZetCode Mono Visual Basic Qt tutorial
  2. '
  3. ' In this program, use the QGridLayout
  4. ' to create a New Folder example
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports Qyoto
  10. Public Class VBQApp
  11. Inherits QWidget
  12. Public Sub New()
  13. Me.SetWindowTitle("New Folder")
  14. Me.InitUI()
  15. Me.Resize(350, 300)
  16. Me.Move(300, 300)
  17. Me.Show()
  18. End Sub
  19. Private Sub InitUI()
  20. Dim grid As New QGridLayout(Me)
  21. Dim nameLabel As New QLabel("Name", Me)
  22. Dim nameEdit As New QLineEdit(Me)
  23. Dim text As New QTextEdit(Me)
  24. Dim okButton As New QPushButton("OK", Me)
  25. Dim closeButton As New QPushButton("Close", Me)
  26. grid.AddWidget(nameLabel, 0, 0)
  27. grid.AddWidget(nameEdit, 0, 1, 1, 3)
  28. grid.AddWidget(text, 1, 0, 2, 4)
  29. grid.SetColumnStretch(1, 1)
  30. grid.AddWidget(okButton, 4, 2)
  31. grid.AddWidget(closeButton, 4, 3)
  32. End Sub
  33. Public Shared Sub Main(ByVal args() As String)
  34. Dim qapp As New QApplication(args)
  35. Dim app As New VBQApp
  36. QApplication.Exec()
  37. End Sub
  38. End Class

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

  1. Dim grid As New QGridLayout(Me)

我们创建QGridLayout管理器的实例。

  1. grid.AddWidget(nameLabel, 0, 0)

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

  1. grid.AddWidget(nameEdit, 0, 1, 1, 3)

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

  1. grid.SetColumnStretch(1, 1)

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

布局管理 - 图4

图:新文件夹 example

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