21. 窗口控件
一、窗口控件
之前,我们创建具体的控件实例(例如标签控件、按钮控件等)时都选择了一个父窗体,将控件放到这个窗体上,即使在创建实例时没有选择父窗体,也可以用控件的 setParent(wiget:QWidget) 方法将控件放到父窗体上。如果一个控件没有放到任何窗体上,则这个控件可以单独成为窗口,并且可以作为父窗口来使用,可在其上面添加其他控件,这种控件可以称为程序的独立窗口。
QWidget 控件可以当作普通的容器控件使用,也可以当作独立的窗口来使用。当一个控件有父窗口时,不显示该控件的标题栏;当控件没有父窗口时,会显示标题栏。
QWidget 是可视化控件的基类,而 QWidget 是从 QObject 和 QPaintDevice 类继承而来的,QObject 主要 定义信号和槽的功能,QPaintDevice 主要 定义绘图功能。
我们可以在终端中使用 pip 安装 PySide6 模块。默认是从国外的主站上下载,因此,我们可能会遇到网络不好的情况导致下载失败。我们可以在 pip 指令后通过 -i 指定国内镜像源下载。
pip install pyside6 -i https://mirrors.aliyun.com/pypi/simple
国内常用的 pip 下载源列表:
- 阿里云 https://mirrors.aliyun.com/pypi/simple
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple
用 QWidget 创建实例对象的方法如下:
QWidget(parent:QWidget=None, kind:Qt.WindowType=Qt.WindowType.Widget)
其中 parent 是 父窗口控件,如果没有给 QWidget 传递父窗口控件,QWidget 将会成为独立窗口。QWidget 中的参数 kind 是 Qt.WindowType 类型的枚举值,用于 确定窗口的类型和外观,如果同时选择多个值,可以用 | 符号将多个可选值连接起来。窗口类型和外观与系统有关,取决于系统是否支持窗口类型和外观。
参数 kind 是窗口类型的 Qt.WindowType 类型的枚举值,可以取值如下:
Qt.WindowType.Widget # 默认值,如果QWidget有父容器或者窗口,它是一个控件,如果没有是独立窗口
Qt.WindowType.Window # 不管QWidget是否有父容器或者窗口,它都是窗口
Qt.WindowType.Dialog # 对话框窗口
Qt.WindowType.Sheet # 在Mac系统中,QWidget是一个表单
Qt.WindowType.Drawer # 在Mac系统中,QWidget是一个抽屉
Qt.WindowType.Popup # QWidget是一个弹出式顶层窗口
Qt.WindowType.Tool # QWidget是一个工具窗
Qt.WindowType.ToolTip # QWidget是一个提示窗,没有标题栏和边框
Qt.WindowType.SplashScreen # QWidget是一个欢迎窗
Qt.WindowType.Desktop # QWidget是一个桌面
Qt.WindowType.SubWindow # QWidget是一个子窗口
Qt.WindowType.ForeignWindow # QWidget是由其它程序创建的句柄窗口
Qt.WindowType.CoverWindow # QWidget是一个封面窗口,单行程序最小化是显示该窗口
影响窗口外观的 Qt.WindowType 枚举值取值如下:
Qt.WindowType.MSWindowsFixedSizeDialogHint # 对于不可调整尺寸的对话框添加窄的边框
Qt.WindowType.MSWindowsOwnDC # 为Window系统的窗口添加下上文菜单
Qt.WindowType.BypassWindowManagerHint # 窗口不受窗口管理协议的约束,与具体的操作系统有关
Qt.WindowType.X11BypassWindowManagerHint # 无边框窗口,不受任何任务管理器的管理,如果不是用activareWindow()方法激活,不接受键盘输入
Qt.WindowType.FramelessWindowHint # 无边框和标题栏,无法移动或改变窗口的尺寸
Qt.WindowType.NoDropShadowWindowHint # 不支持拖放操作的窗口
Qt.WindowType.CustomizeWindowHint # 自定义窗口标题栏,不显示窗口的默认提示信息,以下6个可选值可配合该值一起使用
Qt.WindowType.WindowTitleHint # 有标题栏的窗口
Qt.WindowType.WindowSystemMenuHint # 有系统菜单的窗口
Qt.WindowType.WindowMinimizeButtonHint # 有最小化按钮的窗口
Qt.WindowType.WindowMaximizeButtonHint # 有最大化按钮的窗口
Qt.WindowType.WindowMinMaxButtonsHint # 有最小化和最大化按钮的窗口
Qt.WindowType.WindowCloseButtonHint # 有关闭按钮的窗口
Qt.WindowType.WindowContextHelpButtonHint # 有帮助按钮的窗口
Qt.WindowType.MacWindowToolBarButtonHint # 在Mac系统中,添加工具栏按钮
Qt.WindowType.WindowFullscreenButtonHint # 有全屏按钮的窗口
Qt.WindowType.WindowShadeButtonHint # 在最小化按钮处添加背景按钮
Qt.WindowType.WindowStaysOnTopHint # 始终在最前面的窗口
Qt.WindowType.WindowStaysOnBottomHint # 始终在最后面的窗口
Qt.WindowType.WindowTransparentForInput # 只用于输出,不能用于输入的窗口
Qt.WindowType.WindowDoesNotAcceptFocus # 不接受输入焦点的窗口
Qt.WindowType.MaximizeUsingFullscreenGeometryHint # 窗口最大化时,最大化地占据屏幕
由于 QWidget 可以成为顶层窗口、独立窗口和容器控件,因此 QWidget 的方法根据 QWidget 的功能不同也会有所不同。顶层窗口一定是独立窗口,而独立窗口不一定是顶层窗口,独立窗口也可以有父窗口。QWidget 的一些属性只能用于窗口,一些只能用于控件,一些既可以用于窗口也可以用于控件。
# 实例方法
setWindowIcon(icon:QIcon) -> None # 设置窗口的图标
windowIcon() -> QIcon # 获取窗口的图标
setWindowIconText(text:str) -> None # 设置窗口图标的文字
windowIconText() -> str # 获取窗口图标的文字
windowType() -> Qt.WindowType # 获取窗口类型
windowTitle() -> str # 获取窗口的标题
isWindowModified() -> bool # 获取窗口是否被修改
setWindowModality(windowModality:Qt.WindowModality) -> None # 设置窗口的模式特征
windowModality() -> Qt.WindowModality # 获取窗口的模式特征
isModal() -> bool # 获取窗口是否有模式特征
setWindowOpacity(level:float) -> None # 设置窗口的不透明度,参数从0到1
windowOpacity() -> float # 获取窗口的不透明度
setWindowState(state:Qt.WindowState) -> None # 设置窗口状态
windowState() -> Qt.WindowState # 获取窗口状态
activateWindow() -> None # 激活窗口
isActiveWindow() -> bool # 获取窗口是否处于活动状态
setMinimumWidth(width:int) -> None # 设置窗口或控件的最小宽度
setMinimumHeight(height:int) -> None # 设置窗口或控件的最小高度
setMinimumSize(size:QSize) -> None # 设置窗口或控件的最小尺寸
setMinimumSize(width:int, height:int) -> None # 设置窗口或控件的最小尺寸
isMinimized() -> bool # 获取是否处于最小化状态
setMaximumWidth(width:int) -> None # 设置窗口或控件的最大宽度
setMaximumHeight(height:int) -> None # 设置窗口或控件的最大高度
setMaximumSize(size:QSize) -> None # 设置窗口或控件的最大尺寸
setMaximumSize(width:int, height:int) -> None # 设置窗口或控件的最大尺寸
isMaximized() -> bool # 获取是否处于最大化状态
setFixedWidth(width:int) -> None # 设置窗口或控件的固定宽度
setFixedHeight(height:int) -> None # 设置窗口或控件的固定高度
setFixedSize(size:QSize) -> None # 设置窗口或控件的固定尺寸
setFixedSize(width:int, height:int) -> None # 设置窗口或控件的固定尺寸
isFullScreen() -> bool # 获取是否处于全屏状态
isHidden() -> bool # 获取是否处于隐藏状态
isEnabled() -> bool # 获取激活状态
setVisible(visible:bool) -> None # 设置窗口是否可见
isVisible() -> bool # 获取是否可见
isWindow() -> bool # 获取是否是独立窗口
window() -> QWidget # 返回控件所在的独立窗口
setAutoFillBackground(enabled:bool) -> None # 设置是否自动填充背景色
autoFillBackground() -> bool # 获取是否自动填充背景色
setFont(font:QFont) -> None # 设置字体
font() -> QFont # 获取字体
setPalette(palette:QPalette) -> None # 设置调色板
palette() -> QPalette # 获取调色板
setCursor(cursor:QCursor) -> None # 设置光标
cursor() -> QCursor # 获取光标
unsetCursor() -> None # 重置光标,使用父窗口的光标
setContextMenuPolicy(policy:Qt.ContextMenuPolicy) -> None # 设置右键快捷菜单的弹出策略
contextMenuPolicy() -> Qt.ContextMenuPolicy # 获取右键快捷菜单的弹出策略
addAction(action:Qt.QAction) -> None # 添加一个动作,以便形成右键快捷菜单
addActions(actions:Sequence[Qt.QAction]) -> None # 添加多个动作,以便形成右键快捷菜单
insertAction(before:Qt.QAction, action:Qt.QAction) -> None # 在指定动作之前添加一个动作
insertActions(before:Qt.QAction, actions:Sequence[Qt.QAction]) -> None # 在指定动作之前添加多个动作
actions() -> List[Qt.QAction] # 获取所有动作
scroll(dx:int, dy:int) -> None # 窗口中的控件向左、向下移动指定的像素,参数可为负
scroll(dx:int, dy:int, r:QRect) -> None # 窗口中的控件向左、向下移动指定的像素,参数可为负
setUpdatesEnabled(enable:bool) -> None # 设置是否可以对窗口进行刷新
update(r:Uinon[QRect, QRegion]) -> None # 刷新窗口的指定区域
update(x:int, y:int, width:int, height:int) -> None # 刷新窗口的指定区域
repaint(rect:QRect) -> None # 重绘指定区域
repaint(x:int, y:int, width:int, height:int) -> None # 重绘指定区域
resize(size:QSize) -> None # 重新设置窗口工作区的尺寸
resize(width:int, height:int) -> None # 重新设置窗口工作区的尺寸
size() -> QSize # 获取窗口工作区的尺寸
move(point:QPoint) -> None # 移动左上角到指定位置
move(x:int, y:int) -> None # 移动左上角到指定位置
pos() -> QPoint # 获取窗口左上角位置
x() -> int # 获取窗口左上角X坐标
y() -> int # 获取窗口左上角Y坐标
setGeometry(rect:QRect) -> None # 设置窗口的尺寸和位置
setGeometry(x:int, y:int, width:int, height:int) -> None # 设置窗口的尺寸和位置
geometry() -> QRect # 获取窗口的尺寸和位置
rect() -> QRect # 获取窗口的尺寸和位置
childrenRect() -> QRect # 获取子控件的尺寸和位置
frameSize() -> QSize # 获取窗口的尺寸
frameGeometry() -> QRect # 获取窗口的尺寸和位置
setBaseSize(size:QSize) -> None # 设置控件的合适尺寸
setBaseSize(width:int, height:int) -> None # 设置控件的合适尺寸
baseSize() -> QSize # 获取控件的合适尺寸
setContentsMargins(margins:QMargins) -> None # 设置左、上、右、下的页边距
setContentsMargins(left:int, top:int, right:int, bottom:int) -> None # 设置左、上、右、下的页边距
setWhatsThis(test:str) -> None # 设置按Shift+F1查看的提示信息
setToolTip(text:str) -> None # 设置控件的提示信息
setToolTipDuration(msec:int) -> None # 设置控件的提示信息持续时间(毫秒)
childAt(point:QPoint) -> QWidget # 获取指定位置处的控件
childAt(point:QPointF) -> QWidget # 获取指定位置处的控件
childAt(x:int, y:int) -> QWidget # 获取指定位置处的控件
setLayout(layout:QLayout) -> None # 设置窗口或控件内的布局
layout() -> QLayout # 获取窗口或控件内的布局
setLayoutDirection(direction:Qt.LayoutDirection) -> None # 设置布局的排列方向
setParent(parent:QWidget) -> None # 设置控件的父控件
setParent(parent:QWidget, f:Qt.WindowType) -> None # 设置控件的父控件
parentWidget() -> QWidget # 获取控件的父控件
setSizeIncrement(size:QSize) -> None # 设置窗口变化时的增量值
setSizeIncrement(width:int, height:int) -> None # 设置窗口变化时的增量值
sizeIncrement() -> QSize # 获取窗口变化时的增量值
setMask(bitmap:QBitmap) -> None # 设置遮掩,白色部分不显示,黑色部分显示
setStyle(style:QStyle) -> None # 设置窗口的风格
setAttribute(attribute:Qt.WidgetAttribute, on:bool=true) -> None # 设置窗口的属性
setAcceptDrops(on:bool) -> None # 设置是否接受鼠标的拖放
setMouseTracking(enable:bool) -> None # 设置是否追踪鼠标的移动事件
hasMouseTracking() -> bool # 获取是否追踪鼠标的移动事件
underMouse() -> bool # 获取鼠标是否处于光标之下
setWindowFilePath(filePath:str) -> None # 在窗口上记录一个路径
mapFrom(parent:QWidget, pos:QPoint) -> QPoint # 将父容器的点映射成控件坐标系下的点
mapFrom(parent:QWidget, pos:QPointF) -> QPointF # 将父容器的点映射成控件坐标系下的点
mapTo(parent:QWidget, pos:QPoint) -> QPoint # 将控件的点映射成父容器坐标系下的点
mapTo(parent:QWidget, pos:QPointF) -> QPointF # 将控件的点映射成父容器坐标系下的点
mapFromGlobal(pos:Qpoint) -> QPoint # 将屏幕坐标系中的点映射成控件的点
mapFromGlobal(pos:QpointF) -> QPointF # 将屏幕坐标系中的点映射成控件的点
mapToGlobal(pos:QPoint) -> QPoint # 将控件的点映射成屏幕坐标系下的点
mapToGlobal(pos:QPointF) -> QPointF # 将控件的点映射成屏幕坐标系下的点
mapFromParent(pos:QPoint) -> QPoint # 将父容器坐标系下中的点映射成控件的点
mapFromParent(pos:QPointF) -> QPointF # 将父容器坐标系下中的点映射成控件的点
mapToParent(pos:QPoint) -> QPoint # 将控件的点映射成父容器坐标系下的点
mapToParent(pos:QPointF) -> QPointF # 将控件的点映射成父容器坐标系下的点
grab(rectangle:QRect=QRect(QPoint(0, 0), QSize(-1, -1))) -> QPixmap # 截取控件指定范围的图像,默认为整个控件
grabKeyboard() -> None # 获取所有的键盘输入事件,其它控件不再接受键盘输入事件
releaseKeyboard() -> None # 不再获取键盘输入事件
grabMouse() -> None # 获取所有的鼠标输入事件,其它控件不再接受鼠标输入事件
grabMouse(cursor:QCursor) -> None # 获取所有的鼠标输入事件并改变光标形状
releaseMouse() -> None # 不再获取鼠标输入事件
# 静态方法
static find(id:int) -> QWidget # 根据控件的识别ID号或句柄ID号获取控件
static keyboardGrabber() -> QWidget # 返回键盘获取的控件
static mouseGrabber() -> QWidget # 获取鼠标获取的控件
static setTabOrder(first:QWidget, second:QWidget) -> None # 设置窗口上的控件的Tab顺序
# 槽方法
show() -> None # 显示窗口
close() -> bool # 关闭窗口,如果成功返回True
hide() -> None # 隐藏窗口
setHidden(hidden:bool) -> None # 设置隐藏状态
raise_() -> None # 提升控件,放到栈控件的顶部
lower() -> None # 降低控件,放到栈控件的底部
setWindowTitle(title:str) -> None # 设置窗口标题
setWindowModified(modified:bool) -> None # 设置文档是否修改过
setFocus() -> None # 设置窗口获得焦点
setStyleSheet(styleSheet:str) -> None # 设置窗口或控件的样式表
showFullScreen() -> None # 全屏显示
showMaximized() -> None # 最大化显示
showMinimized() -> None # 最小化显示
showNormal() -> None # 最大化或者最小化显示后恢复成正常显示
update() -> None # 更新窗口
repaint() -> None # 调用paintEvent事件重新绘制窗口
QWidget 窗口的常用信号如下:
windowIconChanged(icon:QIcon) # 窗口图标改变时发送信号
windowIconTextChanged(iconText:str) # 窗口图标文本改变时发送信号
windowTitleChanged(title:str) # 窗口标题改变时发送信号
customContextMenuRequested(pos:QPoint) # 右键弹出自定义菜单时发送信号
用 show() 方法可以 显示窗口,用 hide() 方法可以 隐藏窗口,也可以用 setVisible(visible:bool)方法和 setHidden(hidden:bool) 方法 设置窗口的可见性,用 isVisible() 和 isHidden() 方法 判断窗口是否可见,用 close() 方法可以 关闭窗口。close() 方法的返回值 bool 表示关闭事件是否被接受,也就是窗口是否真的被关闭了。
当窗口被关闭时,首先向这个窗口发送一个关闭事件 closeEvent(event:QCloseEvent),如果事件被接受,则窗口被隐藏;如果事件被拒绝,则什么也不做。如果创建窗口时用 setAttribute(Qt.WA_QuitOnClose, on=True)方法设置了 Qt.WA_QuitOnClose 属性,则窗口对象会被析构(删除),大多数类型的窗口都默认设置了这个属性。
如果显示多个窗口,则窗口之间是有先后顺序的,用 raise_() 方法可 把窗口放到前部,用 lower() 方法可以 把窗口放到底部。
我们可以用 setWindowState(state:Qt.WindowStates)方法 设置窗口的状态,其中参数 state 是 Qt.WindowStates 类型的枚举值,可以取值如下:
Qt.WindowState.WindowNoState # 无标识,正常状态
Qt.WindowState.WindowMinimized # 最小化状态
Qt.WindowState.WindowMaximized # 最大化状态
Qt.WindowState.WindowFullScreen # 全屏状态
Qt.WindowState.WindowActive # 激活状态

窗口尺寸的设置是在屏幕坐标系下进行的,屏幕坐标系的原点在左上角,向右表示 x 方向,向下表示 y 方向。我们可以用 x()、y() 和 pos() 方法可以 获得窗口左上角的坐标,用 frameGeometry() 方法可以 获得窗口框架的几何参数,用 frameSize() 方法可以 获得框架的宽度和高度,用 geometry() 方法可以 获得工作区的几何参数,包括左上角的位置和宽度、高度,用 rect()、size()、width() 和 height() 方法可以 获得工作区的宽度、高度。
我们还可以用 move(int:x, int:y) 方法可以 将窗口左上角移动到坐标 (x,y) 处,用 move(point:QPoint) 方法可以 将窗口左上角移动到 QPoint 处,用 resize(width:int, height:int) 方法可以 设置工作区的宽度和高度,用 resize(size:QSize) 方法可以 将工作区宽度和高度设置成 size,用 setGeometry(x:int,y:int,w:int,h:int) 方法可以将工作区的 左上角移动到 (x,y) 处,宽度改为 width,高度改为 height。
在主窗口中通常需要弹出一些需要进行设置或确认信息的对话框,在对话框没有关闭之前,通常不能对其他窗口进行操作,这就是窗口的模式。用 setWindowModality(modality:Qt.WindowModality) 方法 设置窗口的模式特性,其中参数 modality 是 Qt.WindowModality 类型的枚举值,可以取值如下:
Qt.WindowModality.NonModal # 非模式,可以和程序的其他窗口进行交互操作
Qt.WindowModality.WindowModal # 窗口模式,在未关闭当前窗口时,将阻止与该窗口的父辈窗口的交互操作
Qt.WindowModality.ApplicationModal # 应用程序模式,在未关闭当前窗口时,将阻止窗口与任何其他窗口的交互操作
用 setLayout(layout:QLayout) 方法可以 设置窗口的布局,用 layout() 方法可以 获取窗口的布局,用 setLayoutDirection(direction:Qt.LayoutDirection) 方法可以 设置布局的方向,其中参数 direction 是 Qt.LayoutDirection类型的枚举值,可以取值如下:
Qt.LayoutDirection.LeftToRight
Qt.LayoutDirection.RightToLeft
Qt.LayoutDirection.LayoutDirectionAuto
用 setAttribute(attribute:Qt.WidgetAttribute, on:bool=True) 方法可以 设置窗口的属性,用 testAttribute(attribute:Qt.WidgetAttribute) 方法可以 测试是否设置了某个属性,其中参数 attribute 是 Qt.WidgetAttribute 类型的枚举值,可以取值如下:
Qt.WidgetAttribute.WA_DeleteOnClose # 调用close()方法时删除窗口而不是隐藏窗口
Qt.WidgetAttribute.WA_QuitOnClose # 最后一个窗口如果有Qt.WidgetAttribute.WA_DeleteOnClose属性,则执行close()方法发时退出程序
Qt.WidgetAttribute.WA_AcceptDrops # 窗口接受拖拽的数据
Qt.WidgetAttribute.WA_AlwaysShowToolTips # 窗口失效时也能显示提示信息
Qt.WidgetAttribute.WA_Disabled # 窗口处于失效状态,不接收键盘和鼠标的输入
Qt.WidgetAttribute.WA_DontShowOnScreen # 窗口隐藏
Qt.WidgetAttribute.WA_ForceDisabled # 即使父窗口处于激活状态,窗口也强制失效
Qt.WidgetAttribute.WA_TransparentForMouseEvents # 窗口和其子窗口忽略鼠标事件
Qt.WidgetAttribute.WA_RightToLeft # 布局方向从右向左
Qt.WidgetAttribute.WA_ShowWithoutActivating # 当不激活窗口时,显示窗口
在窗口或控件上右击鼠标时,将弹出右键快捷菜单(上下文菜单),用 setContextMenuPolicy(policy:Qt.ContextMenuPolicy) 方法 设置弹出快捷菜单的策略和处理方式,其中 policy 是 Qt.ContextMenuPolicy 类型的枚举值,可取值如下所示:
Qt.ContextMenuPolicy.NoContextMenu # 控件没有自己特有的快捷菜单,使用控件父窗口或父容器的快捷菜单
Qt.ContextMenuPolicy.DefaultContextMenu # 鼠标右键事件交给控件的contextMenuEvent()函数处理
Qt.ContextMenuPolicy.ActionsContextMenu # 右键快捷菜单是控件或窗口的actions()方法获取的动作
Qt.ContextMenuPolicy.CustomContextMenu # 用户自定义快捷菜单,右击鼠标时,发射sustomContextMenuRequested(point:QPoint)信号
Qt.ContextMenuPolicy.PreventContextMenu # 鼠标右键事件交给控件的mousePressEvent()和mouseReleaseEvent()函数进行处理
我们新建一个 ui.py 文件,用来存放 UI 相关的代码。
from PySide6.QtWidgets import QWidget
from PySide6.QtGui import QIcon
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
window.setObjectName("Window") # 2.设置窗口的唯一标识
window.setWindowTitle("基于PySide6的桌面应用程序") # 3.设置窗口的标题
icon = QIcon("assets/images/1.ico")
window.setWindowIcon(icon) # 4.设置窗口的图标
window.setStyleSheet("background-color:pink") # 5.设置背景颜色
window.setWindowOpacity(0.8) # 6.设置窗口不透明度
我们新建一个 widget.py 文件,用来存放业务逻辑相关的代码。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
二、菜单和动作
一般菜单栏由多个菜单构成,菜单下面又有动作、子菜单和分隔条,子菜单下面又有动作,还可以有子菜单,动作上有图标和快捷键。
建立一个菜单分为 3 步。
- 需要建立放置菜单的容器,即菜单栏;
- 在菜单栏上添加菜单,或者在菜单上添加子菜单;
- 在菜单栏、菜单或子菜单下面添加动作,并为动作编写槽函数。

菜单一般不执行命令,其作用类似于标签,只有动作才可以发送信号,执行关联的槽函数。
2.1、菜单栏
QMenuBar 类是所有窗口的 菜单栏,用户需要再次基础上添加不同的 QMenu 和 QAction 类。我们可以通过如下方式创建菜单栏。
QMenuBar(parent:QWidget=None)
QMenuBar 类的常用方法如下:
addMenu(menu:QMenu) -> QAction # 添加已经存在的菜单
addMenu(text:str) -> QMenu # 用字符串添加菜单,并返回菜单
addMenu(icon:QIcon, text:str) -> QMenu # 用图标和字符串添加菜单,并返回菜单
insertMenu(before:QAction, menu:QMenu) -> QAction # 在指定的动作之前插入菜单
addAction(action:QAction) -> None # 添加已经存在的动作
addAction(text:str) -> QAction # 用字符串添加动作,并返回动作
addSeparator() -> QAction # 添加分隔符
insertSeparator(before:QAction) -> QAction # 在指定的动作之前插入分隔符
clear() -> None # 清空菜单
setCornerWidget(widget:QWidget, corner:Qt.Corner=Qt.Corner.TopRightCorner) -> None # 在菜单栏的角落位置添加控件
cornerWidget(corner:Qt.Corner=Qt.Corner.TopRightCorner) -> QWidget # 获取角落位置的控件
setActiveAction(action:QAction) -> None # 设置高亮显示的动作
actionAt(point:QPoint) -> QAction # 获取指定位置的动作
actionGeometry(action:QAction) -> QRect # 获取动作的矩形
QMenuBar 类的常用信号如下:
hovered(action:QAction) # 当光标划过控件时发射信号
triggered(action:QAction) # 当单击菜单栏上的菜单或动作时发射信号
菜单栏上可以添加菜单、动作和分隔条,用 addMenu(menu:QMenu) 方法和 addAction(action:QAction) 方法可以 添加已经提前定义好的菜单和动作。用 addMenu(text:str) 方法和 addMenu(icon:QIcon, text:str) 方法可以 创建并添加菜单,并返回新建立的菜单。用 addAction(text:str) 方法可以 用字符串创建并添加动作,并返回动作。
用 setCornerWidget(widget:QWidget, corner:Qt.Corner=Qt.Corner.TopRightCorner) 方法可以 在菜单栏的角落位置添加控件,参数 corner 是 Qt.Corner 类型的枚举值,可以取值如下:
Qt.Corner.TopLeftCorner
Qt.Corner.TopRightCorner
Qt.Corner.BottomLeftCorner
Qt.Corner.BottomRightCorner
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QMenuBar, QLabel
from PySide6.QtWidgets import QVBoxLayout
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.menuBar = QMenuBar(window) # 3.创建菜单栏
self.menuBar.setFixedHeight(30) # 4.设置菜单栏宽度
layout.addWidget(self.menuBar) # 5.添加菜单栏到布局中
self.file_menu = self.menuBar.addMenu("文件(&F)") # 6.向菜单栏中添加菜单
self.file_menu.addAction("新建文件") # 7.向菜单中添加动作
self.file_menu.addAction("新建文件夹")
self.file_menu.addSeparator() # 8.添加分隔符
self.file_menu.addAction("打开文件")
self.file_menu.addAction("打开文件夹")
self.file_menu.addSeparator()
self.file_menu.addAction("保存")
self.file_menu.addAction("另存为")
self.file_menu.addAction("全部保存")
self.file_menu.addSeparator()
self.file_menu.addAction("退出")
self.label = QLabel(window) # 9.创建标签控件
layout.addWidget(self.label) # 10.添加标签控件到布局中
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QAction
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.menuBar.hovered.connect(self.menuBar_hovered) # 3.鼠标悬停菜单时触发信号
self.__ui.menuBar.triggered.connect(self.menuBar_triggered) # 4.动作被激活时触发信号
def menuBar_hovered(self, action:QAction):
text = f"你悬停在【{action.text()}】菜单项"
self.__ui.label.setText(text)
def menuBar_triggered(self, action:QAction):
text = f"你点击了【{action.text()}】菜单项"
self.__ui.label.setText(text)
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
2.2、菜单
菜单 QMenu 用于 放置动作和子菜单,通常将动作分类放到不同的菜单中。菜单 QMenu 继承自 QWidget。用 QMenu 类创建菜单实例的方法如下所示:
QMenu(parent:QWidget=None)
QMenu(title:str, parent:QWidget=None)
QMenu 类表示菜单栏中的菜单,可以显示文本和图标,但是并不负责执行操作,类似于 QLable 的作用。
QMenu 类的常用方法如下:
# 实例方法
addMenu(menu:QMenu) -> QAction # 在菜单中添加子菜单
addMenu(title:str) -> QMenu # 在菜单中添加新子菜单
addMenu(icon:QIcon, title:str) -> QMenu # 在菜单中添加新子菜单
insertMenu(before:QAction, menu:QMenu) -> QAction # 在指定的动作之前插入菜单
addAction(action:QAction) -> None # 在菜单中添加已经存在的动作
addAction(text:str) -> QAction # 在菜单中添加新动作
addAction(icon:QIcon, title:str) -> QAction # 在菜单中添加新动作
addSeparator() -> QAction # 添加分隔符
addSection(text:str) -> QAction # 添加分隔符
addSection(icon:QIcon, text:str) -> QAction # 添加分隔符
insertSeparator(before:QAction) -> QAction # 在指定的动作之前插入分隔符
insertSection(before:QAction, text:str) -> QAction # 在指定的动作之前插入分隔符
insertSection(before:QAction, icon:QIcon, text:str) -> QAction # 在指定的动作之前插入分隔符
removeAction(action:QAction) -> None # 从菜单中删除动作
clear() -> None # 清空菜单
isEmpty() -> bool # 判断菜单是否为空
actions() -> List[QAction] # 获取动作列表
actionAt(point:QPoint) -> QAction # 获取指定位置的动作
columnCount() -> int # 获取列数
menuAction() -> QAction # 获取菜单动作
setSeparatorsCollapsible(collapse:bool) -> None # 设置是否可以折叠分隔符
setTearOffEnabled(enable:bool) -> None # 设置是否可以拖动分隔符
showTearOffMenu() -> None # 以拖动方式显示菜单
showTearOffMenu(pos:QPoint) -> None # 以拖动方式显示菜单
hideTearOffMenu() -> None # 隐藏拖动菜单
isTearOffEnabled() -> bool # 判断是否可以拖动分隔符
isTearOffMenuVisible() -> bool # 判断是否显示拖动菜单
setTitle(title:str) -> None # 设置菜单标题
title() -> str # 获取菜单标题
setIcon(icon:QIcon) -> None # 设置菜单图标
icon() -> QIcon # 获取菜单图标
setActiveAction(action:QAction) -> None # 设置活跃的动作高亮显示
activeAction() -> QAction # 获取活跃的动作
setDefaultAction(action:QAction) -> None # 设置默认动作
defaultAction() -> QAction # 获取默认动作
popup(pos:QPoint, at:QAction=None) -> None # 弹出菜单
# 静态方法
exec(actions:Sequence[QAction], pos:QPoint, at:QAction=None, parent:QWidget=None) # 在指定位置显示菜单,当pos无法确定位置时,用父控件的parent辅助确定位置
QMenu 类常用的信号及其说明如下:
aboutToHide() # 窗口即将隐藏时发射信号
aboutToShow() # 窗口即将显示时发射信号
hovered(action:QAction) # 鼠标悬停时发射信号
triggered(action:QAction) # 鼠标单击时发射信号
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QMenuBar, QMenu, QLabel
from PySide6.QtWidgets import QVBoxLayout
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.menuBar = QMenuBar(window) # 3.创建菜单栏
self.menuBar.setFixedHeight(30) # 4.设置菜单栏宽度
layout.addWidget(self.menuBar) # 5.添加菜单栏到布局中
self.file_menu = QMenu() # 6.创建菜单
self.menuBar.addMenu(self.file_menu) # 7.将菜单添加到菜单栏中
self.file_menu.setTitle("文件(&F)") # 8.设置菜单标题
self.file_menu.addAction("新建文件") # 9.向菜单中添加动作
self.file_menu.addAction("新建文件夹")
self.file_menu.addSeparator() # 10.添加分隔符
self.file_menu.addAction("打开文件")
self.file_menu.addAction("打开文件夹")
self.file_menu.addSeparator()
self.file_menu.addAction("保存")
self.file_menu.addAction("另存为")
self.file_menu.addAction("全部保存")
self.file_menu.addSeparator()
self.file_menu.addAction("退出")
self.label = QLabel(window) # 11.创建标签控件
layout.addWidget(self.label) # 12.添加标签控件到布局中
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QAction
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.file_menu.aboutToShow.connect(self.menu_about_to_show) # 3.菜单将要被显示时触发信号
self.__ui.file_menu.aboutToHide.connect(self.menu_about_to_hide) # 4.菜单将要被隐藏时触发信号
self.__ui.file_menu.hovered.connect(self.menu_hovered) # 5.鼠标悬停菜单时触发信号
self.__ui.file_menu.triggered.connect(self.menu_triggered) # 6.动作被激活时触发信号
def menu_about_to_show(self):
self.__ui.label.setText("菜单将要被显示")
def menu_about_to_hide(self):
self.__ui.label.setText("菜单将要被隐藏")
def menu_hovered(self, action:QAction):
text = f"你悬停在【{action.text()}】菜单项"
self.__ui.label.setText(text)
def menu_triggered(self, action:QAction):
text = f"你点击了【{action.text()}】菜单项"
self.__ui.label.setText(text)
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
2.3、动作
动作 QAction 是定义菜单和工具栏的基础,单击菜单或工具栏上的动作可以触发动作的 triggered() 信号,执行动作关联的槽函数,完成需要完成的工作。动作在菜单中以项(item)的形式显示,在工具栏中以按钮的形式显示。
动作 QAction 继承自 QObject,位于 QtGui 模块中。用 QAction 创建动作对象的方法如下所示:
QAction(parent:QObject=None)
QAction(text:str, parent:QObject=None)
QAction(icon:Union[QIcon, QPixmap], text:str, parent:QObject=None)
其中 parent 通常是 窗口、工具栏、菜单栏 或 菜单;text 是 显示的文字,如果将动作放到菜单或工具栏上,text 将成为菜单或工具栏中按钮的文字;icon 是 图标,将成为菜单或工具栏中按钮的图标。
QAction 类的常用方法如下:
# 实例方法
setText(text:str) -> None # 设置菜单项文本
text() -> str # 获取菜单项文本
setIcon(icon:QIcon) -> None # 设置菜单项的图标
icon() -> QIcon # 获取菜单项图标
setIconVisibleInMenu(visible:bool) -> None # 设置图标是否显示在菜单中
isIconVisibleInMenu() -> bool # 获取图标是否显示在菜单中
setData(data:Any) -> None # 设置菜单项数据
data() -> Any # 获取菜单项数据
setToolTip(tip:str) -> None # 设置菜单项提示
setStatusTip(statusTip:str) -> None # 设置状态提示
setWhatsThis(what:str) -> None # 设置按Shift+F1键时的提示
setCheckable(checkable:bool) -> None # 设置菜单项是否可选
isCheckable() -> bool # 获取菜单项是否可选
isChecked() -> bool # 获取菜单项是否选中
isEnabled() -> bool # 获取菜单项是否可用
isVisible() -> bool # 获取菜单项是否可见
setShortcutVisibleInContextMenu(show:bool) -> None # 设置快捷键是否显示在右键菜单中
setShortcuts(key:QKeySequence) -> None # 设置快捷键
setShortcuts(shortcuts:QKeySequence.StandardKey) # 设置快捷键
setFont(font:QFont) -> None # 设置菜单项字体
font() -> QFont # 获取菜单项字体
setMenu(menu:QMenu) -> None # 设置菜单项的子菜单
menu() -> QMenu # 获取菜单项的子菜单
setActionGroup(group:QActionGroup) -> None # 设置菜单项的动作组
setSeparator(enable:bool) -> None # 设置菜单项是否为分隔符
setAutoRepeat(repeat:bool) -> None # 设置菜单项是否自动重复
autoRepeat() -> bool # 获取菜单项是否自动重复
# 槽方法
setChecked(checked:bool) -> None # 设置菜单项是否选中
setEnabled(enabled:bool) -> None # 设置菜单项是否可用
setDisabled(disabled:bool) -> None # 设置菜单项是否失效
setVisible(visible:bool) -> None # 设置菜单项是否可见
resetEnabled() -> None # 重置菜单项是否可用
hover() -> None # 发送hover()信号
trigger() -> None # 发送tigger(bool)信号
toggle() -> None # 发送toggle(bool)信号
QAction 类常用信号及其说明如下:
changed() # 改变时发射信号
checkableChanged(checkable:bool) # 可选状态改变时发射信号
enabledChanged(enabled:bool) # 启用状态改变时发射信号
hovered() # 鼠标悬停时发射信号
toggled(arg__1:bool) # 状态翻转时发射信号
triggered(checked:bool=false) # 鼠标单击时发射信号
visibleChanged() # 可见状态改变时发射信号
对于互斥的一些动作,需要将其放到一个组中,可以先用 group=QActionGroup(parent:QWidget) 创建一个对象,然后用 group.addAction(action:QAction) 方法把动作放到一个组中,并将 setExclusive(exclusive:bool) 设置成True,这样就可以保证组内的动作是互斥的。
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QMenuBar, QMenu, QLabel
from PySide6.QtWidgets import QVBoxLayout
from PySide6.QtGui import QAction, QKeySequence
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.menuBar = QMenuBar(window) # 3.创建菜单栏
self.menuBar.setFixedHeight(30) # 4.设置菜单栏宽度
layout.addWidget(self.menuBar) # 5.添加菜单栏到布局中
self.file_menu = QMenu("文件(&F)") # 6.创建菜单
self.menuBar.addMenu(self.file_menu) # 7.将菜单添加到菜单栏中
self.new_file_action = QAction("新建文件") # 8.创建动作
self.file_menu.addAction(self.new_file_action) # 9.将动作添加到菜单中
self.new_file_action.setShortcut("Ctrl+N") # 10.设置快捷键
self.new_folder_action = QAction("新建文件夹")
self.file_menu.addAction(self.new_folder_action)
self.file_menu.addSeparator() # 11.添加分隔符
self.open_file_action = QAction("打开文件")
self.open_file_action.setShortcut(QKeySequence.StandardKey.Open)
self.open_file_action.setShortcutVisibleInContextMenu(True) # 12.设置快捷键可见
self.open_folder_action = QAction("打开文件夹")
self.file_menu.addActions([self.open_file_action, self.open_folder_action]) # 13.将动作列表添加到菜单中
self.file_menu.addSeparator()
self.save_action = QAction("保存", shortcut=QKeySequence.fromString("Ctrl+S"), shortcutVisibleInContextMenu=True)
self.save_as_action = QAction("另存为", shortcut=QKeySequence.fromString("Ctrl+Shift+S"), shortcutVisibleInContextMenu=True)
self.save_all_action = QAction("全部保存")
self.file_menu.addActions([self.save_action, self.save_as_action, self.save_all_action])
self.file_menu.addSeparator()
self.exit_action = QAction("退出", shortcut=QKeySequence.fromString("Ctrl+Q"), shortcutVisibleInContextMenu=True)
self.file_menu.addAction(self.exit_action)
self.label = QLabel(window) # 14.创建标签控件
layout.addWidget(self.label) # 15.添加标签控件到布局中
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QAction
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.new_file_action.hovered.connect(lambda:self.action_hovered(self.__ui.new_file_action)) # 4.鼠标悬停菜单时触发信号
self.__ui.new_file_action.triggered.connect(lambda:self.action_triggered(self.__ui.new_file_action)) # 5.点击菜单时触发信号
self.__ui.new_folder_action.hovered.connect(lambda:self.action_hovered(self.__ui.new_folder_action))
self.__ui.new_folder_action.triggered.connect(lambda:self.action_triggered(self.__ui.new_folder_action))
self.__ui.open_file_action.hovered.connect(lambda:self.action_hovered(self.__ui.open_file_action))
self.__ui.open_file_action.triggered.connect(lambda:self.action_triggered(self.__ui.open_file_action))
self.__ui.open_folder_action.hovered.connect(lambda:self.action_hovered(self.__ui.open_folder_action))
self.__ui.open_folder_action.triggered.connect(lambda:self.action_triggered(self.__ui.open_folder_action))
self.__ui.save_action.hovered.connect(lambda:self.action_hovered(self.__ui.save_action))
self.__ui.save_action.triggered.connect(lambda:self.action_triggered(self.__ui.save_action))
self.__ui.save_as_action.hovered.connect(lambda:self.action_hovered(self.__ui.save_as_action))
self.__ui.save_as_action.triggered.connect(lambda:self.action_triggered(self.__ui.save_as_action))
self.__ui.save_all_action.hovered.connect(lambda:self.action_hovered(self.__ui.save_all_action))
self.__ui.save_all_action.triggered.connect(lambda:self.action_triggered(self.__ui.save_all_action))
self.__ui.exit_action.hovered.connect(lambda:self.action_hovered(self.__ui.exit_action))
self.__ui.exit_action.triggered.connect(lambda:self.action_triggered(self.__ui.exit_action))
def action_hovered(self, action:QAction):
text = f"你悬停在【{action.text()}】菜单项"
self.__ui.label.setText(text)
def action_triggered(self, action:QAction):
text = f"你点击了【{action.text()}】菜单项"
self.__ui.label.setText(text)
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
在使用 PySide6 中的菜单时,只有
QAction菜单项可以执行操作,QMenuBar菜单栏和QMenu菜单都是不会执行任何操作的。
三、工具栏
与菜单类似,工具栏也是一组命令的集合地。菜单上放置的动作也可放到工具栏上,实现工具栏和菜单的同步。工具栏上除了放置动作外,还可以放置其他控件等。
工具栏 QToolBar 用于存放动作,动作在工具栏中一般呈现按钮状态。QToolBar 继承自 QWidget。用 QToolBar 类创建工具栏实例的方法如下:
QToolBar(parent:QWidget=None)
QToolBar(title:str, parent:QWidget=None)
其中 title 是工具栏控件的 标题名称,可通过 setWindowTitle(title:str) 方法修改;parent 是工具栏所在的 窗口。
QToolBar 类常用方法如下:
# 实例方法
addAction(action:QAction) -> None # 添加已经存在的动作到工具栏
addAction(text:str) -> QAction # 创建并添加动作,返回新建立的动作
addAction(icon:QIcon, title:str) -> QAction # 创建并添加动作,返回新建立的动作
addSeparator() -> QAction # 添加分隔符
insertSeparator(before:QAction) -> QAction # 在指定的动作之前插入分隔符
addWidget(widget:QWidget) -> QAction # 添加控件,并返回与控件关联的动作
insertWidget(before:QAction, widget:QWidget) -> QAction # 在指定的动作之前插入控件,并返回与控件关联的动作
clear() -> None # 清空菜单
widgetForAction(action:QAction) -> QWidget # 返回与动作关联的控件
actionAt(x:int, y:int) -> QAction # 返回指定位置处的动作
actionAt(p:QPoint) -> QAction # 返回指定位置处的动作
actionGeometry(action:QAction) -> QRect # 返回指定动作的矩形区域
setFloatable(floatable:bool) -> None # 设置动作是否可以浮在其他窗口上
isFloatable() -> bool # 返回动作是否可以浮在其他窗口上
isFloating() -> bool # 返回动作是否浮在其他窗口上
setMovable(movable:bool) -> None # 设置动作是否可以移动
isMovable() -> bool # 返回动作是否可以移动
iconSize () -> QSize # 返回动作图标大小
setOrientation(orientation:Qt.Orientation) -> None # 设置动作的方向
orientation() -> Qt.Orientation # 返回动作的方向
toolButtonStyle() -> Qt.ToolButtonStyle # 返回动作样式
setAllowedAreas(areas:Qt.ToolButtonArea) -> None # 设置可停靠的区域
allowedAreas() -> Qt.ToolButtonArea # 获取可停靠的区域
isAreaAllowed(area:Qt.ToolButtonArea) -> bool # 获取指定的区域是否可以停靠
toggleViewAction() -> QAction # 切换停靠窗口的可见状态
# 槽函数
setIconSize(iconSize:QSize) -> None # 设置动作图标大小
setToolButtonStyle(toolButtonStyle:Qt.ToolButtonStyle) -> None # 设置动作样式
QToolBar 类常用信号及其说明如下:
actionTriggered(action:QAction) # 工具栏按钮被触发时发射信号
allowedAreasChanged(allowedAreas:Qt.ToolBarArea) # 工具栏按钮显示区域改变时发射信号
iconSizeChanged(iconSize:QSize) # 工具栏按钮图标大小改变时发射信号
movableChanged(movable:bool) # 工具栏移动时发射信号
orientationChanged(orientation:Qt.Orientation) # 工具栏按钮显示的方向改变时发射信号
toolButtonStyleChanged(toolButtonStyle:Qt.ToolButtonStyle) # 文本显示样式改变时发射信号
topLevelChanged(topLevel:bool) # 工具栏浮动属性改变时发射信号
visibilityChanged(visible:bool) # 工具栏按钮是否可见改变时发射信号
用 setOrientation(orientation:Qt.Orientation) 方法可以 设置工具栏的方向,其中 Qt.Orientation 可以取值如下:
Qt.Orientation.Horizontal # 水平
Qt.Orientation.Vertical # 竖直
用 setToolButtonStyle(style:Qt.ToolButtonStyle) 方法可以 设置工具栏上按钮的风格,其中 Qt.ToolButtonStyle 枚举值可以取值如下:
Qt.ToolButtonStyle.ToolButtonIconOnly # 只显示图标
Qt.ToolButtonStyle.ToolButtonTextOnly # 只显示文字
Qt.ToolButtonStyle.ToolButtonTextBesideIcon # 文字在图标的旁边
Qt.ToolButtonStyle.ToolButtonTextUnderIcon # 文字在图标的下面
Qt.ToolButtonStyle.ToolButtonFollowStyle # 遵循风格设置
用 toggleViewAction() 方法返回一个动作对象,通过单击该动作对象可以切换停靠窗口的可见状态,即该动作是一个对停靠控件窗口进行显示或关闭的开关,如果将该动作加到菜单上,对应菜单栏的文字即为停靠窗口的标题名称,这样就可以在菜单上单击对应菜单项进行停靠窗口的关闭和显示。
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QToolBar, QToolButton, QMenu
from PySide6.QtWidgets import QComboBox, QLabel
from PySide6.QtWidgets import QVBoxLayout
from PySide6.QtGui import Qt, QIcon, QAction
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.toolBar = QToolBar() # 3.创建一个工具栏,并添加到布局中
layout.addWidget(self.toolBar)
self.toolBar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) # 4.设置工具栏的显示样式
self.toolBar.setOrientation(Qt.Orientation.Horizontal) # 5.设置工具栏的方向
new_action = QAction(QIcon("assets/images/1.ico"), "新建", self.toolBar) # 6.创建动作,并添加到工具栏中
open_action = QAction(QIcon("assets/images/1.ico"), "打开", self.toolBar)
save_action = QAction(QIcon("assets/images/1.ico"), "保存", self.toolBar)
close_action = QAction(QIcon("assets/images/1.ico"), "关闭", self.toolBar)
self.toolBar.addActions([new_action, open_action, save_action, close_action])
comboBox = QComboBox() # 7.添加其它组件到工具栏中
self.toolBar.addWidget(comboBox)
names = ["木之本樱", "御坂美琴", "夏娜"]
comboBox.addItems(names)
toolButton = QToolButton(self.toolBar) # 8.创建工具按钮,并添加工具按钮到工具栏中
self.toolBar.addWidget(toolButton)
toolButton.setArrowType(Qt.ArrowType.RightArrow) # 9.设置工具按钮的箭头样式
toolButton.setText("文件") # 10.设置工具按钮的文本
toolButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) # 11.设置工具按钮的样式
toolButton.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup) # 12.设置工具按钮菜单弹出模式
menu = QMenu("文件", toolButton) # 13.创建菜单,并添加到工具按钮控件中
toolButton.setMenu(menu)
menu.addActions([new_action, open_action, save_action, close_action]) # 14.往菜单中添加动作
self.label = QLabel(window) # 15.创建标签控件
layout.addWidget(self.label) # 16.添加标签控件到布局中
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QAction
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.toolBar.actionTriggered.connect(self.toolBar_action_triggered) # 3.动作被激活时触发信号
def toolBar_action_triggered(self, action:QAction):
self.__ui.label.setText(f"你点击了【{action.text()}】按钮")
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
如果设置垂直工具栏没有效果,那可能是你先调用
setOrientation(orientation:Qt.Orientation)设置工具栏方向,在将工具栏添加到窗体中。单击工具栏中的
QAction对象默认会发送actionTriggered信号,但是如果为工具栏添加了其它控件,并不会发射actionTriggered信号,而是会发射它们自己的特有信号。
四、状态栏
状态栏 QStatusBar 一般放在独立窗口的底部,用于 显示程序运行过程中的程序状态信息、提示信息、简要说明信息等,这些信息经过一小段时间后会自动消失。状态栏上也可以放置一些小控件等,用于显示永久信息,永久信息不会被实时信息遮挡住。
状态栏 QStatusBar 继承自 QWidget。用 QStatusBar 类创建状态栏实例的方法如下:
QStatusBar(parent:QWidget=None)
其中 parent 是状态的 父窗口,一般是独立窗口。
QStatusBar 类常用方法及其说明如下:
# 实例方法
urrentMessage() -> str # 获取当前显示的信息
addWidget(widget:QWidget, stretch:int=0) -> None # 在状态栏的左侧添加临时的控件,stretch是拉伸比例
insertWidget(index:int, widget:QWidget, stretch:int=0) -> None # 在状态栏的左侧插入临时的控件,stretch是拉伸比例
addPermanentWidget(widget:QWidget, stretch:int=0) -> None # 在状态栏的右侧添加永久性的控件,stretch是拉伸比例
insertPermanentWidget(index:int, widget:QWidget, stretch:int=0) -> None # 在状态栏的右侧插入永久性的控件,stretch是拉伸比例
removeWidget(widget:QWidget) -> None # 从状态栏中移除控件
setSizeGripEnabled(enable:bool) -> None # 设置在右下角是否有三角形
isSizeGripEnabled() -> bool # 获取右下角是否有三角形
hideOrShow() -> None # 确保右边的控件可见
# 槽函数
showMessage(text:str, timeout:int=0) -> None # 显示信息,timeout是显示时间
clearMessage() -> None # 清空信息
QStatusBar 类常用信号及其说明如下:
messageChanged(text:str) # 消息改变时发送信号
用 showMessage(text:str, timeout:int=0) 方法 设置状态栏要显示的信息,显示的信息从状态的左侧开始,其中参数 timeout 的单位是 毫秒,设置信息显示的时间,经过 timeout 毫秒后信息自动消失,如果 timeout = 0,则显示的信息一直保留到调用 clearMessage() 方法或再次调用 showMessage() 方法;
用 addtWidget(widget:QWidget, stretch:int=0) 方法或 insertWidget(index:int, widget:QWidget, stretch:int=0) 方法可以 把其它控件添加到状态栏的左侧,用于显示正常的信息,这些信息会被状态栏的信息遮挡住。
用 addPermanentWidget(widget:QWidget, stretch:int=0) 方法或 insertPermanentWidget(index:int, widget:QWidget, stretch:int=0) 方法可以 把其它控件添加到状态栏的右侧,用于 显示一些永久的信息。其中参数 stretch 用于 指定控件的相对缩放系数,index 是 控件的索引号。
用 removeWidget(widget:QWidget) 方法可以 把控件从状态栏上移除,但控件并没有被真正删除,可以用 addWidget(widget:Widget) 方法和 show() 方法将控件重新添加到状态栏中。
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QStatusBar
from PySide6.QtWidgets import QComboBox, QLabel
from PySide6.QtWidgets import QVBoxLayout
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.label = QLabel(window) # 3.创建标签控件
layout.addWidget(self.label) # 4.添加标签控件到布局中
self.statusBar = QStatusBar(window) # 5.创建一个状态栏
self.statusBar.setFixedHeight(30) # 6.设置状态栏的高度
layout.addWidget(self.statusBar) # 7.添加状态栏控件到布局中
comboBox = QComboBox() # 8.向状态栏中添加控件
names = ["木之本樱", "御坂美琴", "夏娜"]
comboBox.addItems(names)
self.statusBar.addPermanentWidget(comboBox)
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtCore import QTimer, QDateTime
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
timer = QTimer(self) # 3.创建一个QTime定时器对象
timer.start(1000) # 4.启动定时器
timer.timeout.connect(self.update_time) # 5.定时器定时时间到触发
self.__ui.statusBar.messageChanged.connect(self.statusBar_message_changed) # 6.状态栏消息改变时触发
def update_time(self):
datatime = QDateTime.currentDateTime() # 1.获取当前日期时间
text = datatime.toString("yyyy-MM-dd HH:mm:ss") # 2.对日期时间进行格式化
self.__ui.statusBar.showMessage(f"当前日期时间: {text}") # 3.在状态栏中显示一条临时消息
def statusBar_message_changed(self, text:str):
self.__ui.label.setText(text) # 1.设置标签的文本
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
默认情况下,状态栏中的临时消息和添加的控件不能同时显示,否则会发生覆盖重合的情况。此时,我们可以使用
addPermanentWidget(widget:QWidget, stretch:int=0)添加永久性控件来解决。

浙公网安备 33010602011771号