Pyside6 布局管理器(3)--- 控件尺寸、尺寸策略与布局的关系详解

在学习QWidget时我们已经学习了控件尺寸的一些基本设置,比如设置其作为顶层窗口时resize()方法,setGeometry()等方法。但在将控件添加到布局中后我们会发现,这些方法对于QWidget做为子控件时却是无效的。而布局的显示与大小也受到控件的影响。

所以,我们有必要了解这些关于控件尺寸限定的内容,为界面效果的展示建立相应的知识基础。

本章就是对控件的尺寸、尺寸策略及与布局的关系进行详细的介绍。

一、控件尺寸

1.控件尺寸的相关方法

API函数

参数说明

返回值

功能作用

resize(self, arg__1)arg_1:QSizeNone设置控件尺寸

size(self

None

QSize

获取控件的尺寸大小(不含框架)

setMaximumSize(self,maxw,maxh)

maxw:int

maxh:int

None

设置控件的最大尺寸

setMinimumSize(self,minw,minh)

minw:int

minh:int

None

设置控件的最小尺寸

maximumSize(self)

None

QSize

获取控件的最大尺寸

minimumSize(self)

None

QSize

获取控件的最小尺寸

setFixedSize(self,size)

size:QSzie(x,y

None

设置控件尺寸为固定尺寸,无法拉大缩小

setBaseSize(basew,baseh)

Basew:int基础宽度

Baseh:int 基础高度

None

设置控件的基础尺寸

baseSize(self)

None

QSize

获取控件的基础尺寸

setSizeIncrement(w,h)

W:int

H:int

None

设置控件延伸尺寸

sizeIncrement(self)

None

QSize

获取控件的延伸尺寸

sizeHint(self)

None

QSize

获取控件的推荐尺寸

minimumSizeHint(self)

None

QSize

获取控件的最小推荐尺寸

2.控件尺寸方法的含义的简要介绍

为什么说这里是简要介绍,因为对于控件的方法有些实在是用文字描述起来会难以说明白,需要放在具体使用情况下去区分它们用法上的区别。

resize():更改控件的尺寸大小,适用于顶层控件及独立控件。

size():获取控件当前实际尺寸大小。

setMaximumSize( ):设置控件的最大限定尺寸,控件的尺寸调整不允许超过设定值(不限于代码调整)。

maximumSize( ):获取控件设置的最大限定尺寸。

setMinimumSize( ):设置控件的最小限定尺寸,控件的尺寸调整不允许超过设定值(不限于代码调整)。

minimumSize( ):获取控件设置的最小限定尺寸。

setFixedSize( ):固定控件的尺寸,无法随意调整(不限于代码调整)。

setBaseSize( ):设置控件的基础尺寸。此方法任何时候都无法控制控件大小,仅仅起到提示作用。也就是说,设置这个值只是提醒用户,尽量不要将控件界面带下缩放到这个值之下,否则会影响内容的查看,这个方法在后面不再讨论。

baseSize):获取控件的基础尺寸。

setSizeIncrement( ):设置控件在拖动改变大小时调整步幅。windows下没有效果,macOS和linux下才能显示效果。且,需要加载布局和子控件。

sizeIncrement( ):获取控件拖动改变大小的调整步幅。

sizeHint( ):获取控件的建议尺寸,这个尺寸是子控件和布局中控件初始化大小的主要影响因素。即编程人员不使用reSize(),setMaximumSize( )等方法设置控件大小时的初始化尺寸大小。例如,需要多个大小相等的按钮,又不想使用尺寸的set方法。那么,就可以在自定义的QPushButton,通重写sizeHint( ),从而达到实例化多个按钮统一尺寸的目的。此方法的实际使用场景应是在布局中,见后面的小节。

minimumSizeHint( ):获取控件的最小建议尺寸。使用情况同sizeHint()。

二、控件的尺寸

1.顶层窗口的尺寸

1)顶层窗口不做设置的默认尺寸

这里所说的顶层窗口不仅仅是指定QWidget,还包括QLabel、QPushButton等继承自QWidget的控件未设置父对象时作为顶层窗口。我了探究他们在默认情况下尺寸控制情况,编写如下代码:

import sys
from PySide6.QtWidgets import QApplication, QWidget,QPushButton,QCalendarWidget,QMainWindow,QTextEdit,QGroupBox,QToolBoxclass testWindow(QTextEdit):def __init__(self):super(testWindow, self).__init__()self.getSizes(self)@staticmethoddef getSizes(obj):print(obj.size())print(obj.maximumSize())print(obj.minimumSize())print(obj.baseSize())print(obj.sizePolicy())print(obj.sizeIncrement())print(obj.sizeHint())print(obj.minimumSizeHint())if __name__ == '__main__':app = QApplication(sys.argv)window = testWindow()window.show()window.getSizes(window)sys.exit(app.exec())

在内部不装载子控件时:

  • 顶层窗口内部无子控件,QWidget作为顶层窗口时初始化尺寸是size()方法返回值,默认大小为QSize(640,480)。
  • 继承自QWidget的小控件做为顶层窗口且内部无子控件时,控制其初始化尺寸的方法则是sizeHint()。小控件类型不同,默认实现的尺寸大小也是不同的。如QPushButton是QSize(40,23),QLabel是QSize(6,15)。但需要注意的是,如QLabel,默认QSize(6,15)显然不能满足现实要求,那么他的实际在屏幕上展现的width则是标题栏的最小宽度。
  • 比较特殊的QMainWindow,内部无子控件时的默认尺寸是QSize(200,100),即不是size()的返回值,也不是sizeHint()的返回值。

装载子控件后:

  • QWidget、QMainWindow及QGroupBox、QStackedWiget等能够作为容器的控件作为顶层窗口,一部分是根据子控件的大小来计算其初始化大小(子控件大小+内容边距)。而有些则是Qt设置者内部定义了大小,而非size()或者sizeHint()的返回值,如QStackedWiget。
  • QPushButton、QLabel等独立控件作为顶层窗口装载子控件在这里没有讨论的意义,他们装载子控件干啥?

各控件在作为顶层窗口,默认情况下,相关尺寸方法的表现:

  • size()方法返回所有控件实际显示尺寸
  • maximumSize( )返回值为QSize(1677215,1677215),即默认情况可以无限大。
  • minimumSize( )返回值为QSize(0,0),即默认情况下可以缩小至看不到(会保留Title)
  • sizeIncrement( )返回值为QSize(0,0)。根据默认情况下的拖动效果,设计者在设计时内部可能已经实现了它的值QSize(1,1).
  • sizeHint( )返回值QWidget为QSize(-1,-1),其他控件各有不同。
  • minimumSizeHint( )返回值为QSize(-1,-1),其他控件各有不同。

总结:在不做任何设置的情况下,QWidget的初始化显示尺寸依赖的方法各有不同,有的是size()返回值,有的是sizeHint()返回值,有的是设计者内部定义值。作为编程人员,我们没有必要关心这些内容,而对顶层窗口的关注点应该在其设置的相关方法及表现。

设计者:Qt设计人员

编程人员:我们

用户:我们制作的GUI软件的使用者

2)顶层窗口尺寸设置及相关性质

顶层窗口尺寸初始化尺寸的设置方法,在QWidget中已经介绍过,通常我们使用resize()、setGeometry()方法。这些设置方法不仅可以在窗口初始化时使用,也可以在窗口显示后通过调用控件相关信号的方式改变窗口大小。下来,我们将调用了这些方法后,顶层窗口尺寸变化及相关表现进行罗列:

  • 如果resize()方法设置了顶层窗口,窗口的显示大小发生相应改变。
  • 如果设置了setMaximumSize( ),最大化按钮将不可用(无法最大化),窗口拖动改变大小时,最大只能拖动到设置值。
  • 如果设置了setMinimumSize( ),窗口拖动改变大小时,最小只能拖动到设置值(默认情况下可以拖动至只剩Title)。
  • 如果设置了setFixedSize( ),窗口固定大小,无法拖动改变大小,最大化按钮不可用。
  • 如果设置了setSizeIncrement( ),窗口拖动时,无变化。
  • sizeHint()通常是重写此方法,用返回值控制控件初始化大小,在顶层窗口的设置中无法表现。
  • minimumSizeHint( )通常是重写此方法,用返回值控制控件调整时最小值,在顶层窗口的设置中无法表现。

2.子控件未装载进布局时的尺寸

QWidget及其子类做为其他控件的子控件时且不装在进布局时,不做设置默认情况下,其初始化大小为sizeHint()的返回值。可以通过resize()方法改变其大小。其他尺寸方法对这种子控件没有什么作用。

表现上,他不随父控件的大小改变而改变,当父控件尺寸小于其尺寸时,其受到父控件窗口的裁剪。

3.子控件放入子布局时的尺寸

1)默认不做任何尺寸设置的情况

我们先看下面的代码:

from PySide6.QtWidgets import QWidget,QApplication,QGridLayout,QPushButton,QLabel,QTextEdit
import sysclass testWindow(QWidget):def __init__(self):super().__init__()lay = QGridLayout()self.setLayout(lay)self.move(300,300)btn1 = QPushButton()btn2 = QPushButton()btn3 = QPushButton()btn4 = QPushButton()lab = QLabel()lab.setStyleSheet("background:red")textEdit = QTextEdit()lay.addWidget(btn1,0,0)lay.addWidget(btn2,0,1)lay.addWidget(btn3,0,2)lay.addWidget(btn4,1,0)lay.addWidget(lab,1,1,1,2)lay.addWidget(textEdit,2,0,1,3)self.setBaseSize(500,500)self.setSizeIncrement(30,50)self.getSize(self)self.getSize(btn3)self.getSize(lab)self.getSize(textEdit)print(lay.contentsMargins())print(lay.spacing())@staticmethoddef getSize(obj):print("{}的{}".format(obj,obj.size()))print("{}的{}".format(obj,obj.baseSize()))print("{}的{}".format(obj,obj.minimumSize()))print("{}的{}".format(obj,obj.maximumSize()))print("{}的{}".format(obj,obj.sizeIncrement()))print("{}的{}".format(obj,obj.sizeHint()))print("{}的{}".format(obj,obj.minimumSizeHint()))if __name__ == '__main__':app = QApplication(sys.argv)win = testWindow()win.show()sys.exit(app.exec())

运行结果:

控制台显示结果:

<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(640, 480)
<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(500, 500)
<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(0, 0)
<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(16777215, 16777215)
<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(30, 50)
<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(278, 272)
<__main__.testWindow(0x1aba16a4440) at 0x000001ABA360FE80>的PySide6.QtCore.QSize(154, 151)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(640, 480)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(16777215, 16777215)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(40, 23)
<PySide6.QtWidgets.QPushButton(0x1aba16a2a30) at 0x000001ABA36122C0>的PySide6.QtCore.QSize(40, 23)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(640, 480)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(16777215, 16777215)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(6, 15)
<PySide6.QtWidgets.QLabel(0x1aba16a8190) at 0x000001ABA36123C0>的PySide6.QtCore.QSize(6, 15)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(640, 480)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(16777215, 16777215)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(0, 0)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(256, 192)
<PySide6.QtWidgets.QTextEdit(0x1aba16b9650) at 0x000001ABA3612440>的PySide6.QtCore.QSize(71, 71)
<PySide6.QtCore.QMargins(11, 11, 11, 11) at 0x000001ABA36124C0>
6

从结果我们可以看出父窗口的初始化宽度和最小值是其sizeHitn()和minimumSizeHint()的返回值,而不是size()和minimumSize(),而且其初始化大小是受到内部子控件大小控制的。

父窗口的初始化宽度 = textEdit的sizeHint().width() + 2 * contentsMargin

                                  = 256+22

                                  = 278

父窗口的初始化高度 = btn的sizeHint().height()  *  2 + textEdit的sizeHint().height() +

                                    2 * contentsMargin +  2 * spaceing()

                                  = 23 *2 + 192 + 2 * 11 + 2* 6

                                  = 272

另外,通过计算我们也可以知道父窗口的最小值也是由其内部子控件的minimumSizeHint()决定的。所有得出以下结论,我们的得出以下结论:

  • size()返回值非子控件显示的实际值。各个子控件都是以自己的sizeHint()值进行呈现。跨行跨列的控件不遵从sizeHint()值展现,而是相应的进行伸展填充多余的空间(这与其尺寸策略有关)。
  • 当尺寸策略非Fixed的情况下或非Maximum,子控件的尺寸主要受伸缩因子控制。控件按照设置的伸缩因子所占比例分享除内容编剧和空白间距的空间。子控件会跟随父控件的大小改变而改变,最大值由父控件的大小决定,最小值由其minimumSizeHint()决定。
  • 当任意子控件的尺寸策略为Fixed,此子控件的尺寸固定为sizeHint(),不受其他任何因素影响,也不能跟随父控件大小改变而改变。这种固定是分为两个方向的,宽度固定,高度可变;宽度可变,高度固定;宽度和高度均固定。
  • 当任意子控件尺寸策略为Maximum,此子控件将以最大值进行显示,sizeHint()做为其最大值;多余空间由其他尺寸策略非Fixed或非Maximum的子控件占据。即,此控件的最大值被限制为maximumSize(),父控件尺寸增大的改变无法对其造成影响。
  • 父窗口不做任何尺寸设置的默认情况下,尺寸大小由内部控件的行列数(决定spacing的多少)及控件的类型(sizeHint()值)、内容边距值决定的。跨行跨列的情况下,各控件类型中sizeHint()最大值进行计算。

2)对含有布局的父控件进行设置

父控件为顶层窗口时,顶层窗口的设置依然如第二.1中所表现的一致。

子控件的尺寸设置表现及各因素之间的影响方式:

  • 子控件的resize()方法设置无效,其尺寸只受到sizeHint()方法、伸缩因子和其尺寸策略QSizePolicy影响。
  • sizeHint()控制控件初始化大小,通过重写可改变默认初始化大小的显示值。需要注意的是如果如果自定义控件时只重写sizeHint()而未重写minimumSizeHint( ),则默认minimumSizeHint( )的值等于sizeHint()的值。
  • 如果设置了setMaximumSize( ),除尺寸策略Fixed的限制,初始化显示值为设置值,控件尺寸跟随父控件的变化最大不能超过设置值。
  • 如果设置了setMinimumSize( ),除尺寸策略Fixed的限制,控件尺寸跟随父控件的变化最小不能超过设置值。
  • 如果设置了setFixedSize( ),子控件固定大小,其他任何因素无法对齐尺寸大小造成影响,也无法跟随父控件大小改变而改变大小。
  • setSizeIncrement( )对于子控件无任何影响。
  • minimumSizeHint( )通常是重写此方法,用返回值控制控件调整时最小值。

布局的影响因素较多,主要的因素组合产生的变化上面已经列出,需要大家多进行测试才能熟练的运用。

三、控件的尺寸策略

1.控件尺寸策略的含义

上一节我们已经接触到了控件的尺寸策略,不同的尺寸策略的设置将影响控件初始化尺寸的显示及跟随父窗口变化时自身尺寸的变化。这种变化的体现主要在控件的尺寸的自适应伸缩性质上。

比如,上一节的例子中,我们看到按钮的尺寸策略水平方向为minimum,竖直方向为Fixed。即:水平方向上sizeHint()为其最小值,但足够使用,且不能小于sizeHint()的值。在有额外空间时,它可以伸展,但与其他伸展策略相较没有优势。竖直方向上,其尺寸固定,不能大也不能小。

这里还要解释两个概念,一个是额外空间。所谓的额外空间就是窗口的尺寸能够计算的分配控件大于控件sizeHint()。比如,窗口尺寸是QSize(300,300),水平布局(LeftToRight)中放入两个按钮控件,水平方向上扣除两侧内容边距22(11*2),再扣除两个按钮间的空白间距6,那么每个按钮在水平方向上可分配的尺寸就应该是:L = (300-22-6)/2 = 136。而按钮的sizeHint()水平方向最小尺寸为65,那么这中间相差的71就是额外的控件。

另一个概念是伸展策略的优势:两个按钮的水平方向上的尺寸策略均为minimum。此时,我们将其中一个按钮的水平策略改为minimumExpanding(水平方向上sizeHint()为其最小值,但足够使用,且不能小于sizeHint()的值。在有额外空间时,它尽可能获得空间)。可以看到minimumExpanding策略比minimum策略在水平伸展的定义上有更高优先级。所以,当我们这么设置时,minimum策略的按钮尺寸水平方向上为sizeHint(),而minimumExpanding策略的按钮将获得71*2的额外尺寸。垂直方向两个按钮的尺寸策略是固定值,所以虽然有多余空间,但按钮垂直尺寸不在占用。

要具体了解他的作用与功能,就需要了解他的相关参数与含义,如下:

枚举类

枚举常量

枚举值

功能描述

QSizePolicy. Policy

Fixed

0

sizeHint()是唯一可接受的替代方案,因此小部件永远不会增长或收缩(例如:按钮的垂直方向)。

Minimum

1

sizeHint()是最小的,也是足够的。小部件可以被扩展,但是如果遇到高优先级的尺寸策略设置控件,它没有优势(例如,按钮的水平方向)。它不能小于sizeHint()提供的大小。

Maximum

2

sizeHint()是一个最大值。如果其他小部件需要空间,则小部件可以缩小任何量而不会受到损害(例如,分隔线)。它不能大于sizeHint()提供的大小。

Preferred

3

sizeHint()是最好的,但小部件可以缩小,仍然有用。小部件可以扩展,但是它比sizeHint()(默认的QWidget策略)大没有优势

Expanding

4

sizeHint()是一个合理的大小,但小部件可以缩小,仍然是有用的。小部件可以利用额外的空间,因此它应该获得尽可能多的空间(例如水平滑块的水平方向)。

MinimumExpanding

5

sizeHint()是最小的,也是足够的。小部件可以利用额外的空间,因此它应该获得尽可能多的空间(例如水平滑块的水平方向)。

Ignored

6

sizeHint()被忽略。小部件将获得尽可能多的空间。

从上面的枚举值和含义可以看到,控件的尺寸策略的设置都是以sizeHint()值为参考标准的。他可以分为两个方面进行理解。

第一个方面,跟随父控件变化的情况。

  • 不变。Fixed策略,可以理解为setFixedSize(),不能变化。
  • 单向变化。Minimum和MinimumExpanding策略,只能跟随父控件变大,不能再变小了。Maximum策略相反,只能跟随父控件变小,不能再变大了。
  • 双向变化。Preferred、Expanding、Ignored可随父控件的变化而变化。

第二个方面,初始化时尺寸占用空间扩展。

  • 固定值。Fixed策略,不受其他控件影响。
  • 优先级占用空间。Maximum < Minimum = Preferred < MinimumExpanding = Expanding < Ignored。

        用两个控件的尺寸策略设置作为比较,来说明他们的优先级。在QHBoxLayout布局中,两个控件A和B,水平策略设置如下:

        当A为Ignored时,B控件除非设置为Fixed,其他策略设置均会被压缩完空间,所有控件均被A占有。

        当A为Maximum,B为除Maximum和Ignored外的其他策略时,A的水平方向大小为其sizeHint(),剩余水平空间被B占用;B为Maximum时,A和B平分水平空间。

        当A为Minimum或Preferred,B为MinimumExpanding或Expanding时,A的水平方向大小为其sizeHint(),剩余水平空间被B占用;B为Minimum或Preferred时,A和B平分水平空间。

        当A为MinimumExpanding或Expanding时,B除Ignored外其他策略时,均会被压缩至sizeHint(),多余控件被A占用。B为MinimumExpanding或Expanding时,A和B平分水平空间。

       不再做例子,自己试验。

2.控件的尺寸策略设置及QSizePolicy类的相关方法

控件尺寸策略的设置我们在QWidget的学习时已经学过,设置通过QWidget.setSizePolicy()方法,参数即是QSizePolicy类。获取使用QWidget.sizePolicy()方法。

下面是QSizePolicy类的初始化方法和其他相关方法:

API函数

参数说明

返回值

功能作用

QSizePolicy(HV,type=DefaultType)

H:QSizePolicy.Policy

V:QSizePolicy.Policy

type:QSizePolicy.ControlType

三个参数均为Qt枚举类型

None

添加空白部件

setControlType(self, type)

type: QSizePolicy.ControlType

None

设置与此大小策略适用的小组件关联的控件类型

controlType(self)

None

QSizePolicy.ControlType

返回与应用此大小策略的小组件关联的控件类型

setRetainSizeWhenHidden(self, retainSize)

retainSize:bool

None

设置布局在隐藏时是否应保留构件的大小。如果是 ,则不会通过隐藏小部件来更改布局

retainSizeWhenHidden(self)

None

bool

返回布局在隐藏时是否应保留小组件的大小。默认为Flase

setHeightForWidth(self, b)

b:bool

None

设置高度依赖于宽度

hasWidthForHeight(self)

None

bool

查看是否设置高度依赖于宽度

setWidthForHeight(self, b)

b:bool

None

设置宽度依赖于高度

hasWidthForHeight(self)

None

bool

查看是否设置宽度依赖于高度

setHorizontalPolicy(self, d)

QSizePolicy.Policy

None

设置水平方向尺寸策略

horizontalPolicy(self)

None

QSizePolicy.Policy

获取水平方向尺寸策略

setVerticalPolicy(self, d)

QSizePolicy.Policy

None

设置垂直方向尺寸策略

verticalPolicy(self)

None

QSizePolicy.Policy

获取垂直方向尺寸策略

setHorizontalStretch(self, stretchFactor)

stretchFactor: int

None

设置水平方向伸缩因子

horizontalStretch(self)

None

stretchFactor: int

获取水平方向的伸缩因子

setVerticalStretch(self, stretchFactor)

stretchFactor: int

None

设置垂直方向伸缩因子

verticalStretch(self)

None

stretchFactor: int

获取垂直方向的伸缩因子

expandingDirections(self)

None

Qt.Orientation

返回小部件在那个方向上能利用更多空间

transposed(self)

None

None

交换水平和垂直方向的尺寸策略及伸缩因子3

transposed(self)

None

QSizePolicy.Policy

返回一个交换了水平和垂直方向的策略及伸缩因子的尺寸策略对象

QSizePolicy的初始化方法前两个参数是个枚举类,分别指定水平和竖直两个方向的尺寸策略,具体枚举值及含义我们在上一小节已经学过。最后一个参数也是一个枚举类:

枚举类

枚举常量

枚举值

功能描述

QSizePolicy.controlType

DefalutType

未指定时的默认类型

ButtonBox

一个QDialogButtonBox的实例

CheckBox一个QCheckBox的实例
ComboBox一个QComboBox的实例
Frame一个QFrame的实例
GroupBox一个QGroupBox的实例
Label一个QLabel的实例
Line一个QQFrame类型为VLine或HLine的实例
LineEdit一个LineEdit的实例
PushButton一个PushButton的实例
RadioButton一个RadioButton的实例
Slider一个QSlider的实例
SpinBox一个QSpinBox的实例
      TableWidget一个QTableWidget的实例
ToolButton一个QToolButton的实例

通常,QSizePolicy的此参数可以忽略,并不是必要的。如果需要也可以通过setControlType(self, type)方法进行设置。这个参数用于指定此策略应当应用于控件的类型。它被一些样式使用,特别是QMacStyle,用于在部件之间插入适当的间距。例如,macOS Aqua指南规定按钮之间应间隔12像素,而垂直堆叠的单选按钮只需要6像素。

setHorizontalPolicy(self, d)和setHorizontalPolicy(self, d)则是分别设置控件水平和竖直方向上的尺寸策略。

expandingDirections(self)方法的返回值是基于尺寸策略的设置决定的。比如,如果按钮控件的默认尺寸策略水平方向为Minimum,垂直方向为Fixed,那么相应的返回值就是Qt.Orietnation.Horizeontal。

setHorizontalStretch(self, stretchFactor)和setVerticalStretch(self, stretchFactor)的作用和QLayout.addStrecth()作用相同。但建议使用布局的伸缩因子方法。

setHeightForWidth(self, b)作用是控制窗口部件的高度是否随其宽度的变化而变化。但是,它并没有进行实现,当 setHeightForWidth 设置为 True 时,需要重写 heightForWidth( ) 函数来指定在给定宽度 w 下窗口部件应有的高度。这通常用于那些其高度自然依赖于宽度的控件,例如标签(当文本换行时)或某些自定义绘制的控件。相应的setWidthForHeight(self, b)也是一样。

setRetainSizeWhenHidden(self, retainSize)方法设置布局在控件隐藏时是否应保留小部件的大小。如果retainSize为true,则不会通过隐藏小部件来更改布局。

四、例子

本例子基本使用前面学过的内容,仅有QFormLayout未学,将在后面的小节进行学习。例子中实现两个槽函数功能作为演示,其他的功能大家可以自己发挥。

from PySide6.QtWidgets import QWidget,QApplication,QFormLayout,QPushButton,\QLabel,QSizePolicy,QHBoxLayout,QVBoxLayout,QLineEdit
from PySide6.QtCore import Qt
from PySide6.QtGui import QAction,QIcon,QMovie
import sys,randomclass customLab(QLabel):def __init__(self):super(customLab, self).__init__()font = self.font()font.setFamily("微软雅黑")font.setWordSpacing(20.0)self.setFont(font)self.setText(self.randomLetter())def mousePressEvent(self, ev):if ev.button() == Qt.MouseButton.LeftButton:self.setText(self.randomLetter())def randomLetter(self):self.letterList = [0] * 5for i in range(len(self.letterList)):self.letterList[i] = chr(random.randint(65,90))string = "".join(self.letterList)return stringclass LoginWindow(QWidget):def __init__(self):super().__init__()self.setFixedSize(400,500)self.setWindowTitle("登陆界面")mainLayout = QVBoxLayout()self.setLayout(mainLayout)mainLayout.setContentsMargins(0,0,0,0)pictureLab = QLabel()pictureLab.setFixedHeight(self.height() / 2)pictureLab.setScaledContents(True)movie = QMovie(pictureLab)movie.setFileName("../exmaple/蒲公英.gif")movie.start()pictureLab.setMovie(movie)accountLab = QLabel("账号:")accountline = QLineEdit()accountline.setPlaceholderText("请输出账号")passwordLab = QLabel("密码:")passwordLine = QLineEdit()passwordLine.setPlaceholderText("请输入密码")passwordLine.setEchoMode(QLineEdit.EchoMode.Password)eyeAction = QAction(passwordLine)eyeAction.setIcon(QIcon("../exmaple/close-eye.PNG"))eyeAction.triggered.connect(self.setEye)passwordLine.addAction(eyeAction,QLineEdit.ActionPosition.TrailingPosition)acpwLayout = QFormLayout()acpwLayout.setContentsMargins(80,0,80,0)acpwLayout.setSpacing(20)acpwLayout.addRow(accountLab,accountline)acpwLayout.addRow(passwordLab,passwordLine)checkLine = QLineEdit()checkLine.setPlaceholderText("点击更换验证码")checkLine.setVisible(False)checkLab = customLab()checkLab.setVisible(False)checkLayout = QHBoxLayout()checkLayout.addWidget(checkLine)checkLayout.setContentsMargins(80,0,80,0)checkLayout.setSpacing(20)checkLayout.addWidget(checkLab)loginBtn = QPushButton("登   陆")loginBtn.setFixedHeight(40)loginBtn.clicked.connect(self.login)triggerQRLab = QLabel("<<<<二维码登陆")triggerQRLab.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)triggerPhoenLab = QLabel(">>>>手机登陆")loginLayout = QHBoxLayout()loginLayout.addWidget(triggerQRLab)loginLayout.addWidget(loginBtn)loginLayout.addWidget(triggerPhoenLab)registerLab = QLabel("<a href='#'>注册账号</a>")registerLab.setAlignment(Qt.AlignmentFlag.AlignCenter)registerLab.setTextInteractionFlags(Qt.TextInteractionFlag.LinksAccessibleByMouse)forgetLab = QLabel("<a href='#'>忘记密码</a>")forgetLab.setAlignment(Qt.AlignmentFlag.AlignCenter)registerLayout = QHBoxLayout()registerLayout.addWidget(registerLab)registerLayout.addWidget(forgetLab)messageLab = QLabel("  版权声明:xxx制作       备案号:xxxxxxxxxxxx")mainLayout.addWidget(pictureLab)mainLayout.addSpacing(30)mainLayout.addLayout(acpwLayout)mainLayout.addLayout(checkLayout)mainLayout.addLayout(loginLayout)mainLayout.addLayout(registerLayout)mainLayout.addWidget(messageLab)self.checkLine = checkLineself.checkLab = checkLabself.passwordline = passwordLineself.eye = eyeActiondef setEye(self):if self.passwordline.echoMode() == QLineEdit.EchoMode.Password:self.passwordline.setEchoMode(QLineEdit.EchoMode.Normal)self.eye.setIcon(QIcon("../exmaple/open-eye.PNG"))else:self.passwordline.setEchoMode(QLineEdit.EchoMode.Password)self.eye.setIcon(QIcon("../exmaple/close-eye.PNG"))def login(self):self.checkLine.setVisible(True)self.checkLab.setVisible(True)if __name__ == '__main__':app = QApplication(sys.argv)win = LoginWindow()win.show()sys.exit(app.exec())

运行结果:

20241021-214254

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453460.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络资源模板--Android Studio 实现简易新闻App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的简易新闻App 二、项目测试环境 三、项目详情 登录页 用户输入&#xff1a; 提供账号和密码输入框&#xff0c;用户可以输入登录信息。支持“记…

RabbitMQ最新版本4.0.2在Windows下的安装及使用

RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;提供可靠的消息传递和队列服务。它支持多种消息协议&#xff0c;包括 AMQP、STOMP、MQTT 等。本文将详细介绍如何在 Windows 系统上安装和使用最新版本的 RabbitMQ 4.0.2。 前言 RabbitMQ 是用 Erlang 语言开发的 AMQP&…

【Linux】【命令】diff

diff DescriptionsArgumentsExamples直接使用diff命令-u 输出格式-c 输出格式并列输出-s 和 -q 脚本示例示例1&#xff1a;目录及文件差异 Descriptions diff命令用于对比两个文件或者两个文件夹的不同之处&#xff0c;求基本语法如下所示&#xff1a; diff [OPTION]... FILES…

信号与噪声分析——第一节-确定信号的分析

目录 1.确定信号的分析 1.1确定信号的分类&#xff1a; 1.周期信号与非周期信号&#xff1a; 周期信号的定义&#xff1a; 性质&#xff1a; 2.能量信号与功率信号&#xff1a; 定义 区别&#xff1a; 3.基带信号与频带信号&#xff1a; 基带信号的定义&#xff1a; …

使用Matplotlib绘制箱线图:详细指南与示例

在数据分析和可视化领域&#xff0c;箱线图&#xff08;Box Plot&#xff09;是一种强大的工具&#xff0c;用于展示数据的分布特征&#xff0c;包括中位数、四分位数、异常值等。本文将详细介绍如何使用Matplotlib库在Python中绘制箱线图&#xff0c;并通过一个实际的血压数据…

基于微信小程序二手物品调剂系统设计与实现

文章目录 前言项目介绍技术介绍功能介绍核心代码数据库参考 系统效果图文章目录 前言 文章底部名片&#xff0c;获取项目的完整演示视频&#xff0c;免费解答技术疑问 项目介绍 二手物品调剂系统是一种在线平台&#xff0c;旨在促进用户之间的二手物品交易。该系统提供了一个…

数智合同 | 业财一体与履约联动的数字化转型

随着信息化技术的发展&#xff0c;合同数智化管理为应对合同管理挑战提供了新机遇。企业需要深入思考数智化手段在合同管理中的应用&#xff0c;以提高合同管理水平&#xff0c;应对新形势下的市场竞争挑战与合规要求&#xff0c;实现企业的高质量发展。 2024年5月&#xff0c;…

数据中心母线槽测温监控装置的优势和如何选型

在当今数字化高速发展的时代&#xff0c;数据中心成为了信息存储与处理的核心枢纽。而确保数据中心的稳定运行&#xff0c;对于企业和社会来说至关重要。其中&#xff0c;母线作为数据中心电力传输的关键环节&#xff0c;其正常运行直接关系到整个数据中心的可靠性。为了保障数…

2024新手攻略:项目管理工具+PMP备考经验不容错过!

&#xff08;一&#xff09;热门工具大盘点 禅道是一款专注于软件开发项目管理的工具。它涵盖了项目管理的各个环节&#xff0c;包括需求管理、任务分配、缺陷跟踪等。禅道的优势在于其对软件开发流程的深入理解和支持&#xff0c;能够帮助开发团队更好地管理项目进度和质量。…

免费的国标设备端模拟器,支持自定义编程,批量模拟大量国标GB28181设备

GB/T 28181是中国国家公共安全视频监控联网系统&#xff08;简称“国标GB28181”&#xff09;的一套标准&#xff0c;主要用于规范视频监控系统的互联互通。这套标准的实施旨在推动不同厂家设备之间的互操作性&#xff0c;促进视频监控市场的健康发展。本软件是针对GB28181标准…

算法01----移动零(C++)

题目展示 算法原理 我们这里要用到的算法是双指针移动&#xff0c;和我们之前学的快排的核心思想是一样的。我们看看怎么做吧。我会以图片的形式将我的思路告知大家。 这就是整个题目的整体思想算法&#xff0c;大家理解一下&#xff0c;其实这道题目还是很简单的。 代码编写…

02篇 机械考研复试简历保姆级教程,考研简历联系导师邮件复试调剂超全攻略 导师喜欢看到的简历(附模板)

考研复试简历怎么写&#xff1f;导师喜欢看到的简历&#xff08;附模板&#xff09; 复试简历&#xff0c;重要程度max&#xff01;绝非小事一桩&#xff01;它就像是你硬核经历的闪亮外衣&#xff0c;条理清晰、逻辑严谨且设计感十足&#xff0c;一定能在导师心中留下深刻印象…

基于neo4j知识图谱的菜谱推荐系统

&#x1f374; AI菜谱推荐系统让你“煮”事半功倍&#xff01; &#x1f374; 找不到做饭灵感的时候&#xff0c;是不是总觉得“今天吃啥”这道选择题简直是终极挑战&#xff1f;别急&#xff0c;我们基于Neo4j知识图谱的菜谱推荐系统&#xff0c;正是为了解决你的困扰而设计&a…

空洞卷积:Atrous/Dilated convolution - 语义分割中多用到

没办法&#xff0c;我还是很多基础的、底层的模块不通透&#xff0c;读论文难免会受到阻碍&#xff0c;而且这现在科研任务很急了&#xff0c;必须要马上动手实验&#xff0c;全给我弄明白、特别是算法&#xff01; 空洞卷积-可变形卷积-这一个个我都要。 空洞卷积据说在语义分…

【完-网络安全】Windows防火墙及出入站规则

文章目录 防火墙入站和出站的区别域网络、专用网络、公用网络的区别 防火墙 防火墙默认状态一般是出站允许&#xff0c;入站阻止。 入站和出站的区别 入站就是别人来访问我们的主机&#xff0c;也就是正向shell的操作 出站就是反向shell&#xff0c;主机需要主动连接kali&am…

智能指针(3)

目录 可能问题五&#xff1a; 问题分析&#xff1a; 答案格式&#xff1a; shared_ptr的模拟实现 部分1&#xff1a;引用计数的设计(分考点1) 代码实现&#xff1a; 部分2&#xff1a;作为类所必须的部分(分考点2) 代码实现&#xff1a; 部分3&#xff1a;拷贝构造函数…

WPF实现类似网易云音乐的菜单切换

这里是借助三方UI框架实现了&#xff0c;感兴趣的小伙伴可以看一下。 深色模式&#xff1a;​ 浅色模式&#xff1a; ​这里主要使用了以下三个包&#xff1a; MahApps.Metro&#xff1a;UI库&#xff0c;提供菜单导航和其它控件​​​​​​​ 实现步骤&#xff1a;1、使用B…

【JavaEE】——自定义协议方案、UDP协议

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;自定义协议 1&#xff1a;自定义协议 &#xff08;1&#xff09;交互哪些信息 &…

RuoYi-Vue若依 环境搭建 速成

一、若依简介 RuoYi-Vue 是一个开源的后台管理系统&#xff0c;适用于快速开发企业级应用。该平台由两部分组成&#xff1a;前端和后端。 &#xff08;1&#xff09;技术框架 前端技术&#xff1a; Vue.js: 前端框架使用 Vue.js&#xff0c;这是一种流行的JavaScript框架&a…

Python爬虫实战:抓取指定网站数据

一、前言 在互联网时代&#xff0c;数据的价值日益凸显。爬虫技术作为一种获取数据的重要手段&#xff0c;广泛应用于各种场景。本文将通过一个实例&#xff0c;介绍如何使用Python进行网站数据的抓取。 二、环境准备 Python 3.xrequests库BeautifulSoup库 三、代码实现 i…