布置应用程序的主窗口
如果您使用PyQt创建GUI应用程序,那么大多数时候您将使用
QMainWindow
在其之上创建GUI。此类允许您创建主窗口样式的应用程序。
QMainWindow
具有其自己的预定义布局。这种布局将允许您将以下图形组件添加到主窗口:
- 窗口顶部的菜单栏
- 窗口四个侧面中任意一个的一个或多个工具栏
- 窗口底部的状态栏
- 窗口四个侧面中任何一个的一个或多个停靠小部件(但不占用工具栏区域)
- 窗口正中央的中央小部件
对于大多数应用程序,所有这些图形组件都是可选的,但中央小部件除外,而中央小部件是使应用程序正常工作所必需的。
一些应用程序使用唯一且功能齐全的窗口小部件作为其中央窗口小部件。例如,如果您要编码文本编辑器,则可能会使用
QTextEdit
对象作为编辑器的中央窗口小部件。
其他类型的GUI应用程序可能需要更复杂的中央窗口小部件。在这种情况下,您可以使用
QWidget
对象作为中央窗口小部件,然后创建一个布局,其中包含应用程序GUI所需的特定窗口小部件排列。最后一步是将该布局设置为中央窗口小部件的布局。
大多数时候,
QMainWindow
提供的布局足以创建任何类型的GUI应用程序。这种布局将有效地管理窗口上小部件的行为,因此您不必为此担心。
布置应用程序的对话框
GUI应用程序通常使用一个主窗口和一个或多个对话框来构建。对话框是小窗口,可让您与用户进行交流。PyQt提供了
QDialog
来处理对话框的创建。
与
QMainWindow
不同,
QDialog
没有预定义或默认的顶层布局。这是因为对话框可以多种多样,并且包含各种小部件排列和组合。
将所有小部件放置在对话框的GUI上后,需要在该对话框上设置顶层布局。为此,您必须像对待其他任何小部件一样在对话框对象上调用
.setLayout()
。
这是一个对话框样式的应用程序,显示了如何为
QDialog
对象设置顶层布局:
import sys
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QDialogButtonBox,
QFormLayout,
QLineEdit,
QVBoxLayout,
)
class Dialog(QDialog):
def \_\_init\_\_(self):
super().__init__()
self.setWindowTitle("QDialog's Top-Level Layout Example")
dlgLayout = QVBoxLayout()
# Create a form layout and add widgets
formLayout = QFormLayout()
formLayout.addRow("Name:", QLineEdit())
formLayout.addRow("Job:", QLineEdit())
formLayout.addRow("Email:", QLineEdit())
# Add a button box
btnBox = QDialogButtonBox()
btnBox.setStandardButtons(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel
)
# Set the layout on the dialog
dlgLayout.addLayout(formLayout)
dlgLayout.addWidget(btnBox)
self.setLayout(dlgLayout)
if __name__ == "\_\_main\_\_":
app = QApplication(sys.argv)
dlg = Dialog()
dlg.show()
sys.exit(app.exec_())
在这种情况下,应用程序的窗口继承自
QDialog
,因此您具有对话框样式的应用程序。在第16行上,您将创建将用作对话框顶级布局的布局。在第18至21行上,您将创建一个表单布局以在表单中安排一些小部件。
在第24行,添加一个
QDialogButtonBox
对象。您通常会使用
QDialogButtonBox
处理对话框上的按钮。在此示例中,使用两个按钮,即“确定”按钮和“取消”按钮。这些按钮将不具有任何功能,仅用于使对话框更加逼真。
一旦所有小部件和布局都就位,就可以将它们添加到顶层布局。这就是您在第28行和第29行所做的操作。在第30行的最后一步是使用
.setLayout()
将顶级布局设置为对话框的布局。
如果您运行此应用程序,则会在屏幕上看到以下窗口:
最好的做法是为所有对话框设置顶层布局。这样可以确保当用户调整基础窗口的大小时,对话框的GUI会保持一致。否则,您的对话框在用户的眼中可能会显得杂乱无章。
在PyQt布局中管理空间
在使用PyQt的布局管理器将小部件安排在窗口或窗体上时,管理空间(空空间,小部件之间的空间等)是一个常见问题。能够管理此空间是一项重要技能。
在内部,布局使用以下一些窗口小部件属性来管理窗口上的可用空间:
.sizeHint()
包含小部件的建议大小.minimumSizeHint()
包含小部件可保持可用状态的最小尺寸.sizePolicy()
保留布局中小部件的默认行为
布局使用这些属性自动定位小部件并调整其大小,并根据可用空间为每个小部件分配给定的空间量。这样可确保小部件一致地排列并保持可用。
在接下来的三个部分中,您将学习不同类型的布局如何在PyQt中管理空间。
在盒子布局中管理空间
框布局在分配小部件之间的可用空间方面做得很好。但是,有时它们的默认行为还不够,因此您需要手动处理可用空间。为了在这种情况下帮助您,PyQt提供了
QSpacerItem
。此类允许您向框布局中添加空格(或空白框)。
通常,您不需要直接使用
QSpacerItem
。而是,在框布局对象上调用以下某些方法:
.addSpacing(i)
将固定大小i
的不可拉伸空间(或空框)添加到布局中。我必须是一个整数,以像素为单位表示空间的大小。.addStretch(i)
将最小尺寸为0且拉伸因子为i
的可拉伸空间添加到框布局中。我必须是整数。.insertSpacing(index,size)
在位置index
处插入大小为size
的不可拉伸空间。如果index
为负,则在框布局的末尾添加空格。insertStretch(index,Stretch)
在位置index
处插入一个可拉伸的空间,最小大小为0,拉伸因子为拉伸。如果index
为负,则在框布局的末尾添加空格。
当用户调整基础窗口的大小时,可拉伸的间隔物将扩大或缩小以填充空白空间。不可伸缩的垫片将保持相同的大小,而不管基础窗口的大小如何变化。
返回到如何使用垂直布局的示例,然后再次运行该应用程序。如果您拉下窗口的边框,那么您会注意到,拉得越深,按钮之间的空间越多:
发生这种情况是因为布局通过自动扩展其框来处理新的可用空间。您可以通过在布局的末尾添加一个可拉伸的
QSpacerItem
对象来更改此行为。
在示例代码中,如下更新
Window
的初始化程序:
class Window(QWidget):
def \_\_init\_\_(self):
super().__init__()
self.setWindowTitle("QVBoxLayout Example")
self.resize(270, 110)
# Create a QVBoxLayout instance
layout = QVBoxLayout()
# Add widgets to the layout
layout.addWidget(QPushButton("Top"))
layout.addWidget(QPushButton("Center"))
layout.addWidget(QPushButton("Bottom"))
layout.addStretch()
# Set the layout on the application's window
self.setLayout(layout)
在突出显示的行中,可以通过在布局上调用
.addStretch()
将可拉伸的
QSpacerItem
对象添加到布局的末尾。如果再次运行该应用程序,则会出现以下现象:
现在,所有多余的空间都会自动分配给布局底部的可伸缩
QSpacerItem
对象,而不会影响其余小部件的位置或大小。您可以使用此空间管理技术和其他空间管理技术来使您的GUI应用程序看起来良好且美观。
在网格和表单布局中管理空间
网格和表单布局以不同的方式处理可用空间。在这些类型的布局中,您只能处理小部件之间的垂直和水平空间。这些布局提供了三种方法来管理这些空间:
setSpacing(spacing)
将小部件之间的垂直和水平间距都设置为间距。setVerticalSpacing(spacing)
仅将布局中的小部件之间的垂直间距设置为间距。setHorizontalSpacing(spacing)
仅将布局中的小部件之间的水平间距设置为间距。
在所有情况下,间距都是代表像素的整数。现在回到有关如何创建表单布局和更新
Window
的初始化程序的示例,如下所示:
class Window(QWidget):
def \_\_init\_\_(self):
super().__init__()
self.setWindowTitle("QFormLayout Example")
self.resize(270, 110)
# Create a QHBoxLayout instance
layout = QFormLayout()
# Add widgets to the layout
layout.setVerticalSpacing(30)
layout.addRow("Name:", QLineEdit())
layout.addRow("Job:", QLineEdit())
emailLabel = QLabel("Email:")
layout.addRow(emailLabel, QLineEdit())
# Set the layout on the application's window
self.setLayout(layout)
在突出显示的行中,将小部件之间的垂直间隔设置为30像素。如果您再次运行该应用程序,则会看到以下窗口:
现在,各行小部件之间的空间更大。您还可以尝试通过添加一些垂直或水平空间来修改所有网格的工作方式,以修改如何使用网格布局的示例。
结论
创建高质量的GUI应用程序需要将所有图形组件布置成连贯且优美的布局。在PyQt中,一种有效的方法是使用PyQt的布局管理器,该管理器提供了一种用户友好且高效的方式来完成此任务。
在本教程中,您了解了:
- 在GUI上正确放置小部件的好处是什么
- 如何使用PyQt的内置布局管理器以编程方式排列小部件
- 针对您的特定用例使用哪个布局管理器
- 如何在PyQt中布置主窗口样式和对话框样式的应用程序
有了这些知识,您就可以使用PyQt的内置布局创建美观,专业的GUI应用程序。
更多阅读
特别推荐
程序员摸鱼指南
为你精选的硅谷极客资讯,
来自FLAG巨头开发者、技术、创投一手消息
点击下方阅读原文加入 社区会员