前文
PyQt5学习笔记1 - Windows下安装PyQt5
PyQt5学习笔记2 - Designer和Pyuic5
本文概述
VerticalLayout
,HorizontalLayout
,GridLayout
,FormLayout
布局管理入门
Qt Designer提供了4种窗口布局方式, 分别是Vertical Layout
(垂直布局),Horizontal Layout
(水平布局), Grid Layout
(栅格布局)和Form Layout
(表单布局)。它们位于Qt Designer主窗口左侧的Widget Box
(工具箱)里的Layouts
(布局)栏中。
- 垂直布局:控件默认从上往下的顺序进行纵向添加。
- 水平布局:控件默认从左往右的顺序进行横向添加。
- 栅格布局:将窗口控件放入一个网格之中,然后将它们合理的划分成若干行(row)和列(column)。
- 表单布局:控件以两列的形式布局在表单中,其中左列包含标签,右列包含输入控件。
一般进行布局有两种方式,一是通过布局管理器进行布局,二是通过容器控件进行布局。
使用布局管理器布局
以水平布局为例,打开Qt Designer,新建一个Qwidget控件,然后放入两个子控件:LineEdit(文本框),pushButton(按钮)。选中这两个控件然后单击鼠标右键,在弹出的菜单的子菜单中选择"布局"即可以指定选中控件的布局方式了,此处选择"水平布局".
保存转换为.py
文件查看代码,如下:
Horizontal.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.widget = QtWidgets.QWidget(Form)
self.widget.setGeometry(QtCore.QRect(40, 40, 216, 25))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.lineEdit = QtWidgets.QLineEdit(self.widget)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.widget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.pushButton.setText(_translate("Form", "PushButton"))
可以看到,子控件QpushButton
和QlineEdit
在构建的时候指定的父控件对象就是Qwidget
,布局对象QHBoxLayout
指定的父控件对象也是Qwidget
。可以在对象查看器中看到他们的布局关系。
注意
如果是从工具箱拖放布局控件,那么其属性中的 *Margin 默认都是0.
实例题:做一个如下的计算器布局。
注意
GridLayout中按钮默认占据一个方格,对其拉伸就可以占据三个方格。
使用容器进行布局
所谓容器控件就是指能够容纳子控件的控件。使用容器控件,目的是将容器控件中的控件归为一类,以有别于其他控件。当然,容器控件也可以对其子控件进行布局,只不过没有布局管理器常用。
同样以水平布局为例, 新建一个MainWindow,从左侧容器(Containers)导航栏拖入一个Form控件,然后在Form控件中放入Label
, LineEdit
, Button
控件,并对其重命名。
然后选择Form控件,单击鼠标右键选择"布局"->"水平布局",结果如下
转换为python文件,代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(180, 110, 264, 43))
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.frame)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.pushButton = QtWidgets.QPushButton(self.frame)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.lineEdit = QtWidgets.QLineEdit(self.frame)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "姓名"))
self.pushButton.setText(_translate("MainWindow", "确定"))
注意容器QFrame和子控件之间有一个QHBoxLayout可以看到使用容器进行控件布局本质上还是调用布局管理器进行的。
实例:布局一个计算器的界面
- 水平布局(Label, LineEdit, PushButton)
- 垂直布局(Label, LineEdit, PushButton)
- 栅格布局(PushButton)
- 表单布局(Label, LineEdit, PushButton)
Qt Designer 控件属性解读
打开Qt Designer新建一个主窗口MainWindow
, 然后拖入一个Push Button, 并重命名为"开始". 查看右侧属性编辑器, 主要开始解读Geometry
, sizePolicy
, minimumSize
, maximumSize
属性。
绝对布局
最简单的布局方法就是设置geometry
这个属性, Geometry
属性在PyQt主要用来设置控件在窗口中的绝对坐标与自身的大小。如下如所示:
属性 | 值 | 解释 |
---|---|---|
x | 430 | 控件左上角距离窗口左侧430px |
y | 210 | 控件左上角距离窗口上方140px |
宽度 | 75 | 控件宽度为75px |
高度 | 23 | 控件高度为23px |
对应代码如下:
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(430, 210, 75, 23))
self.pushButton.setObjectName("pushButton")
继续完善示例,继续添加一些控件,Label, Double Spin Box拖拽至如下, 对于doubleSpinBox控件重命名(doubleSpinBox_returns_min
, doubleSpinBox_returns_max
, doubleSpinBox_maxdrawdown_min
, doubleSpinBox_maxdrawdown_max
,
doubleSpinBox_sharp_min
, doubleSpinBox_sharp_max
.)
之所以没有改变Label控件的名称,是因为在实际处理业务逻辑的时候,不会与这些Label控件有任何交集。也就是说这些Label控件作用仅仅是显示。
分别使用Vertical Layout
,Grid Layout
, Horizaontal Spacer
, Vertical Spacer
, Vertical Line
对整体进行布局
-
Vertical Spacer
垂直占位控件,起占位作用。 -
Horizontal Spacer
水平占位控件,起占位作用。 -
Vertical Line
垂直线,仅显示一条竖直的线(无实际作用),用来区分两个布局管理器。
修改Vertical Line
的SizeType
属性为Preferred
, sizeHint
宽度设置为200.然后对选中所有控件进行水平布局。
minimumSize
和MaximumSize
属性用来设置控件在布局管理器中最小尺寸和最大尺寸。当设置过大的值的时候回溢出布局管理器,除非调整布局管理器的大小,否则超过部分不予显示。
每个窗口控件都有属于自己的两个尺寸,sizeHint
(尺寸提示),窗口控件的期望尺寸。
minimumSize
(最小尺寸),窗口控件压缩时所能够被压缩到的最小尺寸。
属性 | 值 | 描述 |
---|---|---|
QSizePolicy.Fixed | 0 | 固定值策略,sizeHint() 对应默认值大小是唯一可以接收的改变,因此控件不能放大也不能缩小 |
QSizePolicy.Minimum | GrowFlag | 指定最小值策略,sizeHint() 对应默认值是控件大小的最小值,但可以扩展(不倾向) |
QSizePolicy.Maximum | ShrinkFlag | 指定最大值策略,sizeHint() 对应默认值是控件大小的最大值,但可以被缩小。 |
QSizePolicy.Preferred | GrowFlag| ShrinkFlag |
首选项策略, sizeHint() 对应默认值是最佳效果,允许扩大和缩小,但不倾向与比sizeHint() 更大 |
QSizePolicy.Expanding | GrowFlag| ShrinkFlag| ExpandFlag |
扩展策略,sizeHint 对应的默认值是合理的大小,但控件允许缩小。可以利用额外的空间,因此它将会得到尽可能多的空间(例如:水平方向上的滑块) |
QsizePolicy.MinimumExpanding | GrowFlag| ExpandFlag |
最小扩展策略,sizeHint 的默认值是最小值,并且是足够的,控件允许使用额外的空间,因此它将会得到尽可能多的空间(例如:水平方向上的滑块) |
QSizePolicy.Ignored | ShrinkFlag| GrowFlag| IgnoreFlag |
sizeHint 对应默认值的大小将会被忽略,控件将会获取尽可能多的空间。 |
如有侵权,请联系删除