PyQt5学习笔记3 - 布局管理

前文

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(按钮)。选中这两个控件然后单击鼠标右键,在弹出的菜单的子菜单中选择"布局"即可以指定选中控件的布局方式了,此处选择"水平布局".


image.png

保存转换为.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"))

可以看到,子控件QpushButtonQlineEdit在构建的时候指定的父控件对象就是Qwidget,布局对象QHBoxLayout指定的父控件对象也是Qwidget。可以在对象查看器中看到他们的布局关系。

注意

如果是从工具箱拖放布局控件,那么其属性中的 *Margin 默认都是0.

实例题:做一个如下的计算器布局。

注意

GridLayout中按钮默认占据一个方格,对其拉伸就可以占据三个方格。

使用容器进行布局

所谓容器控件就是指能够容纳子控件的控件。使用容器控件,目的是将容器控件中的控件归为一类,以有别于其他控件。当然,容器控件也可以对其子控件进行布局,只不过没有布局管理器常用。

同样以水平布局为例, 新建一个MainWindow,从左侧容器(Containers)导航栏拖入一个Form控件,然后在Form控件中放入Label, LineEdit, Button控件,并对其重命名。

然后选择Form控件,单击鼠标右键选择"布局"->"水平布局",结果如下


image.png

转换为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可以看到使用容器进行控件布局本质上还是调用布局管理器进行的。

实例:布局一个计算器的界面

  1. 水平布局(Label, LineEdit, PushButton)
  2. 垂直布局(Label, LineEdit, PushButton)
  3. 栅格布局(PushButton)
  4. 表单布局(Label, LineEdit, PushButton)
image.png

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 LineSizeType属性为Preferred, sizeHint宽度设置为200.然后对选中所有控件进行水平布局。

minimumSizeMaximumSize属性用来设置控件在布局管理器中最小尺寸和最大尺寸。当设置过大的值的时候回溢出布局管理器,除非调整布局管理器的大小,否则超过部分不予显示。

每个窗口控件都有属于自己的两个尺寸,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对应默认值的大小将会被忽略,控件将会获取尽可能多的空间。




如有侵权,请联系删除

你可能感兴趣的:(PyQt5学习笔记3 - 布局管理)