第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解
一、概述
QDockWidget类提供了一个可以停靠在QMainWindow中或作为桌面上的顶级窗口浮动的部件。停靠窗口(Dock windows)是放置在QMainWindow主窗口中央窗口部件(Central widget)周围的次要窗口,如下图中央部件周围的白色区域,这块区域老猿称为停靠区域。
根据停靠窗口的属性设置,停靠窗口可以在停靠区域内移动,移动到新区域并由最终用户确定是否浮动。
QDockWidget对象由一个标题栏和内容区域组成。标题栏显示停靠窗口标题、浮动按钮()和关闭按钮。根据QDockWidget的设置,这两个按钮可能被禁用或根本不显示。
QDockWidget的内容区域,实际上是一个它包含的子部件,停靠窗口展示的内容即该子部件的内容,该子部件必须是QWidget或其派生类。
二、QDockWidget的重要属性及关联信号
2.1、Designer中QDockWidget的属性
在Designer中,QDockWidge有如下属性:
2.2、属性及关联信号介绍
2.2.1、floating属性
floating属性表示QDockWidget对象是否浮动在主窗口之上,如果为True表示浮动停靠部件作为漂浮在其父QMainWindow的“顶部”使用独立窗口展现,为False则停靠在在QMainWindow中。缺省为True,可通过方法isFloating()、setFloating(bool
floating)来访问该属性,当此属性改变时,会发射 topLevelChanged(bool floating) 信号,信号签名表示QDockWidget对象现状是否浮动在主窗口之上
2.2.2、features属性
features属性用于设置浮动部件的特征,其类型为枚举类型 QDockWidget.DockWidgetFeatures,特征包括浮动窗是否可关闭(DockWidgetClosable)、是否可移动(DockWidgetMovable)、是否可浮动(DockWidgetFloatable)、是否将标题栏展示在窗口左边成竖直标题栏(DockWidgetVerticalTitleBar)。除了这几个值之外,该特征类型在Designer中还有如下取值:
- AllDockWidgetFeatures:表示同时设置了DockWidgetClosable、DockWidgetMovable、DockWidgetFloatable这三个特征,但不一定设置了DockWidgetVerticalTitleBar特征,但不建议使用这个值,因为Qt或PyQt可能会增加其他特征值时,AllDockWidgetFeatures包括的特征范围可能会增加
- DockWidgetFeatureMask:表示同时设置了DockWidgetClosable、DockWidgetMovable、DockWidgetFloatable、DockWidgetVerticalTitleBar这四个特征,这个DockWidgetFeatureMask值仅在Designer中使用,选择这个特征则自动勾选上述四个特征,但在类中无此枚举值,即代码不识别该值;
- NoDockWidgetFeatures:表示不设置任何特征,在Designer中选择此值自动去掉其他特征,由于此值对应数值为0,代码中如果使用此值与其他值组合,则此值将失效,以其他值为准
- Reserved:这个值在Designer中选择后,将会勾选所有除NoDockWidgetFeatures之外的特征值,但该值在代码中无效。
features属性缺省为 DockWidgetClosable, DockWidgetMovable和DockWidgetFloatable的组合,可通过方法features() 和setFeatures(DockWidgetFeatures features)访问该属性。
当features属性修改时,会发射featuresChanged(QDockWidget.DockWidgetFeatures features)信号。
2.2.3、allowedAreas属性
allowedAreas属性用于控制停靠部件在QMainWindow的停靠区域中可停靠的范围,其类型为枚举类型Qt.DockWidgetArea或其值的组合,分别控制可以停靠在主窗口停靠区域的左边(LeftDockWidgetArea)、右边(RightDockWidgetArea)、顶部(TopDockWidgetArea)、底部(BottomDockWidgetArea)、所有区域(AllDockWidgetAreas)和不能停靠(NoDockWidgetArea)。
allowedAreas属性缺省值为AllDockWidgetAreas,即所有区域都可以停靠,可以通过allowedAreas()和setAllowedAreas(Qt.DockWidgetAreas areas)来访问该属性。
allowedAreas属性发生变更时,QDockWidget会发射allowedAreasChanged(Qt.DockWidgetAreas allowedAreas)信号。
2.2.4、dockWidgetArea和docked属性
dockWidgetArea和docked属性这两个属性在Designer中有设置,dockWidgetArea表示部件的初始停靠位置,取值范围和allowedAreas相同,docked为布尔值,表示是否启用停靠功能,但这两个属性QDockWidget都没有,实际上是用于控制调用QMainWindow的addDockWidget方法,当docked为True时,Designer生成的代码就会调用QMainWindow的addDockWidget方法,addDockWidget第一个参数即为Designer属性的dockWidgetArea,当docked为False时,Designer生成的代码就不会调用QMainWindow的addDockWidget方法。
三、QDockWidget的其他重要方法
除了与属性相关的方法外,QDockWidget还有几个比较重要的方法。
3.1、isAreaAllowed方法
isAreaAllowed方法用于判断QMainWindow的某个停靠区域是否允许停靠,调用语法如下:
bool isAreaAllowed(Qt.DockWidgetArea area)
3.2、setTitleBarWidget方法
setTitleBarWidget方法用于给停靠窗口设置个性化的标题栏,调用语法如下:
setTitleBarWidget(QWidget widget)
说明:
- widget参数可以是任意一个QWidget 或其派生类对象,如果传None,则将原来通过setTitleBarWidget设置的部件取消了,使用缺省的窗口标题代替
- 如果设置了一个有效的QWidget 或其派生类对象作为标题栏,在浮动时不会使用本机窗口装饰(包括关闭按钮),而是使用参数部件作为标题
- 如果无法直接删除浮动窗口的标题栏,可以使用QWidget()不带参数方式构建一个QWidget对象实现相同的效果
- 使用titleBarWidget()方法可以返回该停靠窗口使用的标题栏部件。
3.3、widget和setWidget方法
在概述部分介绍了,QDockWidget对象由一个标题栏和内容区域组成。QDockWidget的内容区域,实际上是一个它包含的子部件,浮动窗口展示的内容即该子部件的内容,该子部件必须是QWidget或其派生类。方法widget和setWidget就是用于访问QDockWidget的内容区域对应的子部件。调用语法如下:
setWidget(QWidget widget)
QWidget widget()
3.4、toggleViewAction方法
toggleViewAction方法返回一个动作对象,该动作对象通过点击后可以切换停靠窗口的可见状态,即该动作是一个对停靠部件窗口显示或关闭的开关,如果将该动作加到菜单上,对应菜单栏的文字即为停靠窗口的title文字,这样就可以在菜单上点击对应菜单项进行停靠窗口的关闭和显示,这个关闭和显示的状态在QMainWindow的快捷菜单中就有这样的功能。下图是QMainWindow的停靠窗口开关状态快捷菜单以及将部分停靠窗口(字体设置、机器人发言字体颜色、本机输入发言字体颜色)对应开关动作加到菜单栏的一个案例截图:
上图中有2个停靠窗口是关闭的,如果所有停靠窗全部显示则如下效果:
上图中黄色标记的标签选项栏对应三个停靠窗。
四、QDockWidget的信号
除了前面介绍属性的时候介绍的信号allowedAreasChanged、featuresChanged、topLevelChanged外,QDockWidget还有2个信号:dockLocationChanged、visibilityChanged。
dockLocationChanged信号在QDockWidget停靠位置因手工拖拽或代码执行导致停靠位置发生变化时发射,包括移动到不同停靠区域或同一停靠区域的不同位置都会发射该信号。信号语法:dockLocationChanged(Qt.DockWidgetArea area)
visibilityChanged信号在QDockWidget可见状态发生变化时发射,这种可见状态发生变化包括显示或隐藏窗口以及QDockWidget对象停靠在选项卡区域时QDockWidget对象对应选项被选中或去选中时。信号语法:visibilityChanged(bool visible)
五、QMainWindow与QDockWidget相关的操作方法以及信号
5.1、引言
QDockWidget除了放在QMainWindow窗口内外,也可以放在其他类型的窗体如QWidget窗口内,但QMainWindow提供了与QDockWidget配套的特性如停靠区域,而其他窗口没有配套特性,QDockWidget在其他窗口中也可以浮动,但拖拽时无法自动停靠,只能通过鼠标双击标题栏回到原始位置。
QMainWindow与QDockWidget相关的特性处理停靠区域的支持外,还提供了与停靠窗口相关的:
- 三个属性:animated、dockNestingEnabled、dockOptions
- 八个方法:addDockWidget、dockWidgetArea、removeDockWidget、resizeDocks、restoreDockWidget、splitDockWidget、tabifiedDockWidgets、tabifyDockWidget
- 一个信号:tabifiedDockWidgetActivated
其中三个属性已经在《第15.11节 PyQt(Python+Qt)入门学习:Qt Designer(设计师)组件Property Editor(属性编辑)界面中主窗口QMainWindow类相关属性详解》进行了介绍,在此不重复介绍。
5.2、addDockWidget方法
QMainWindow的addDockWidget方法用于将对应停靠窗增加到指定区域,调用语法如下:
- addDockWidget(Qt.DockWidgetArea area, QDockWidget dockwidget)
- addDockWidget(Qt.DockWidgetArea area, QDockWidget dockwidget, Qt.Orientation orientation)
参数area用于指定QDockWidget对象的初始停靠区域,orientation确认标题栏是位于顶部水平方向,还是位于左边竖直方向。
5.3、resizeDocks
resizeDocks用于将QMainWindow的多个停靠窗的大小进行调整,调用语法如下:
resizeDocks( Iterable[QDockWidget], Iterable[int], Qt.Orientation)
参数说明:
- Iterable[QDockWidget]:需要调整的多个停靠窗对象组成的迭代类型如列表
- Iterable[int]:每个停靠窗需要调整的宽度或高度
- Qt.Orientation:调整的是宽度还是高度,如果为Qt.Horizontal,调整宽度,否则调整高度
注意:
- 大小的调整受最小和最大大小的约束
- 大小调整不会影响主窗口的大小
- 如果空间有限的情况下,调整时根据各个停靠窗口的相对大小占比进行可以利用空间的调整
5.4、tabifyDockWidget
主窗口的tabifyDockWidget方法用于将主窗口的两个停靠窗口创建一个选项卡式的停靠区域。调用语法:
tabifyDockWidget(QDockWidget first, QDockWidget second)
该方法将将second停靠窗移动到first停靠窗的顶部,在主窗口中创建一个选项卡式停靠区域。如图:
上图荧光笔标记部分为选项卡,蓝色标记部分为停靠窗的内容区域,二者加起来就是一个选项卡式停靠区域,两个停靠窗可以点击下面的选项卡切换。
5.5、splitDockWidget
主窗口的splitDockWidget方法用于将一个停靠窗占据的空间分割成两部分,原有停靠窗放置在第一部分的区域,另一个停靠窗放置在第二部分的区域。调用语法:
splitDockWidget( QDockWidget first, QDockWidget second, Qt.Orientation orientation)
说明:
- orientation:指定分割方向,是水平分隔还是垂直分隔,如果水平分隔,则这两个停靠窗水平方向并列,first在左second在右,如果是垂直分隔,则两个停靠窗上下排列,first在上second在下
- 如果第一个停靠窗已经是选项卡化停靠窗,则第二个停靠窗将作为新选项卡添加,而不是作为第一个的邻居,这是因为单个选项卡只能包含一个停靠部件,此时splitDockWidget的效果与tabifyDockWidget效果相同
- splitDockWidget实际使用时更多的是用于排列相关停靠窗口使用,也即对停靠窗口通过代码进行排列调整
5.6、其他方法简介
QMainWindow的其他4个与QDockWidget相关的方法dockWidgetArea、removeDockWidget、 restoreDockWidget、tabifiedDockWidgets功能非常简单:
- Qt.DockWidgetArea dockWidgetArea(QDockWidget dockwidget)
用于返回dockwidget停靠窗的停靠区,如果dockwidget未加到主窗口中,则返回Qt.NoDockWidgetArea。 - removeDockWidget(QDockWidget dockwidget)
用于将主窗口中的停靠窗dockwidget移除并隐藏它,但dockwidget对象并未释放,还可以继续使用 - bool restoreDockWidget(QDockWidget dockwidget)
将dockwidget恢复成初始创建状态,成功返回True,否则返回False。 - list[QDockWidget] tabifiedDockWidgets(QDockWidget dockwidget)
返回与参数dockwidget指定停靠窗一起成选项卡式排列的所有停靠窗列表。
5.7、tabifiedDockWidgetActivated信号
tabifiedDockWidgetActivated信号为主窗口中的选项卡式排列的停靠窗被选中激活时发射,被激活的停靠窗为信号签名参数。语法如下:
QMainWindow.tabifiedDockWidgetActivated(QDockWidget dockWidget)
六、小结
本章节详细介绍了QDockWidget的属性、方法、信号以及主窗口与QDockWidget相关的属性、方法和信号,由于主窗口提供了对停靠窗口丰富的支撑能力,才使得通过主窗口可以构建友好的用户界面。
广告
老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元,该部分与第十五章的内容基本对应,但同样内容在付费专栏上总体来说更详细、案例更多。本节内容对应付费专栏的《第三十一章、containers容器类部件QDockWidget停靠窗功能介绍》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。