2024-06-11-Pyside6基础开发

本文主要记录Pyside6的基础开发的内容,通过阅读本文,能够实现简单的客户端软件的编写,内容参考B站视频:【已完结】PySide6百炼成真,带你系统性入门Qt

1.环境配置

开发IDE选择Vscode,插件选择PYQT Integation。通过对PYQT Integation的配置,实现Qt Designer的实现。

image-20240611172637101

在安装包的环境中找到pyside6-designer,pyside6-uic,pyside6-rcc,分别配置到PYQT Integation中配置项的对应位置。

image-20240611173538529

image-20240611173722697

后面就直接右键进行新建、编辑、删除等操作了。

2.基本框架

2.1 查看版本

from PySide6 import QtCore
import PySide6

print(PySide6.__version__)
print(QtCore.__version__)
6.5.2
6.5.2

2.2 基本页面

from PySide6.QtWidgets import QApplication,QMainWindow

app = QApplication([])

window = QMainWindow()
window.show()
app.exec()

image-20240611174117887

2.3 基本模块

本文档使用的pyside6版本是6.5.2,在ZEAL中可以看到,该版本的pyside6包含了60个模块。

image-20240613153408278

下面对主要的常用模块进行介绍:

QtChartQtDataVisualization :用于数据可视化,可以绘制二维和三维数据图表

QtCore:包含核心的非GUI功能,处理程序中涉及到时间、文件、目录、数据类型、流、网络、MIME类型、线程或进程等对象

QtGui:包含多种基本图形的类,如窗口集、事件处理、2D图形、基本图像和界面、文字、文本类等

QtWidgets:包含一整套UI元素的组件,用于建立符合系统风格的用户界面

QtNerwork:包含网络编程相关的类,用于TCP/IP、UDP等CS架构的编程实现

QtMultimedia:包含一整套类,用于处理多媒体事件,通过调用API访问摄像头、语音设备等多媒体设备

QtWebSockets:包含一组类,用于实现Websocket协议

QtOpenGL:调用OpenGL库来渲染2D和3D图形,使用QtGUI库与OpenGL库集成

QtSvg:为SVG矢量图片提供方法

Qtsql:提供数据库对象的接口

QtXml:用于处理XML的库,为SAX和DOM API的实现提供方法

模块中也提供了一些用于物联网通讯方面的协议库:如QtBluetooth,QtOPCUA,QtMQTT,QtHTTPServer,QtNFC等等。

3.窗口运行原理

3.1 窗口运行原理

​ 窗口是图形用户界面(GUI)程序开发的基础,我们平常所见的各种图形界面都是在窗口中放置不同的控件、菜单和工具条,实现不同的动作和目的。图形界面程序开发就是在窗口上放置不同类型的控件、菜单和工具条按钮,并为各个控件、菜单和工具条按钮编写代码使其 “活跃” 起来。

PySide6 的 QtWidgets 模块集中了可视化编程的各种窗口和控件,这些窗口和控件一般都是直接或间接从 QWidget 类继承来的。QWidget 是从 QObject 和 QPaintDevice 类继承而来的,QObject 类主要实现信号和槽的功能,QPaintDevice 类主要实现控件绘制的功能。

QWidget 类通常用作独立显示的窗口,这时窗口上部有标题栏,QWidget 类也可以当作普通的容器控件使用,在一个窗口或其他容器中添加 QWidget,再在 QWidget 中添加其他控件。当一个控件有父窗口时,不显示该控件的标题栏;当控件没有父窗口时,会显示标题栏。常用于独立窗口的类还有 QMainWindow 和 QDialog,它们都是从 QWidget 类继承而来的。

继承于QWidget的类

在创建 QWidget 窗口对象之前,需要先介绍一个 QApplication 类。QApplication 类管理可视化 QWidget 窗口,对 QWidget 窗口的运行进行初始化参数设置,并负责 QWidget 窗口的退出收尾工作,因此在创建 QWidget 窗口对象之前,必须先创建一个 QApplication 类的实例,为后续的窗口运行做好准备。

如果不是基于 QWidget 窗口的程序,可以使用 QGuiApplication 类进行初始化,有些程序通过命令行参数执行任务而不是通过 GUI,这时可以使用 QCoreApplication 类进行初始化,以避免初始化占用不必要的资源。

QApplication类的继承关系

​ QApplication 类是从 QGuiApplication 类继承来的,QGuiApplication 类为 QWidget 窗口提供会话管理功能,用户退出时可以友好地终止程序,如果终止不了还可以取消对应的进程,可以保存程序的所有状态用于将来的会话。

QGuiApplication 类继承自 QCoreApplication 类,QCoreApplication 类的一个核心功能是提供事件循环(event loop)。这些事件可以来自操作系统,如鼠标、定时器(timer)、网络,以及其他原因产生的事件都可以被收发。通过调用exec() 函数进入事件循环,遇到 quit() 函数退出事件循环,退出时发送 aboutToQuit() 信号,类似于 Python 的 sys 模块的 exit() 方法。

当某个控件发出信号时,sendEvent() 函数立即处理事件,postEvent() 函数把事件放入事件队列以等待后续处理,处于队列中的事件可以通过 removePostedEvent() 方法删除,也可通过 sendPostedEvent() 方法立即处理事件。

由于 QApplication 类进行可视化界面的初始化工作,因此在任何可视化对象创建之前必须先创建 QApplication 对象,而且还可以通过命令行参数设置一些内部状态。QApplication 类的主要功能有处理命令行参数,设置程序的内部初始状态;处理事件,从窗口接收事件,并通过 sendEvent() 和 postEvent() 发送给需要的窗口;获取指定位置处的窗口(widgetAt())、顶层窗口列表(topLevelWidgets()),处理窗口关闭(closeAllWindows())等事件;使用桌面对象信息进行初始化。

3.2 QWidget窗口

PySide6 的窗口类主要有三种,分别为 QWidgetQMainWindowQDialog,其中 QMainWindow 和 QDialog 从 QWidget 类继承而来。要创建和显示窗口,需要用这 3 个类中的任意一个类实例化对象,并让窗口对象显示并运行起来。

import sys

from PySide6.QtWidgets import QApplication, QWidget

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = QWidget()
    # 3.设置窗口的尺寸
    window.resize(300, 150)
    # 4.移动窗口
    window.move(300, 300)
    # 5.设置窗口标题
    window.setWindowTitle("基于PySide的桌面应用程序")
    # 6.展示窗口
    window.show()
    # 7.执行exec()方法,进入事件循环,若遇到窗口退出命名,返回整数n
    n = app.exec()
    # 8.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(n)
  • 第 1 步是创建 QApplication 类的实例对象 app,为窗口的创建进行初始化,其中 sys.argv 是字符串列表,记录启动程序时的程序文件名和运行参数。sys.argv 的第 1 个元素的值是程序文件名及路径,也可以不输入参数 sys.argv 创建 QApplication 实例对象 app。QApplication 可以接受的两个参数是 -nograb 和 -dograb,-nograb 告诉 Python 禁止获取鼠标和键盘事件,-dograb 则忽略 -nograb 选项功能,而不管 -nograb 参数是否存在于命令行参数中。一个程序中只能创建一个 QApplication 实例,并且要在创建窗口前创建。
  • 第 2 步是用不带参数的 QWidget 类创建 QWidget 窗口实例对象 window,该窗口是独立窗口,有标题栏。
  • 第 3 步是窗口实例对象 window 调用 resize() 方法设置窗口的尺寸。
  • 第 4 步是窗口实例对象 window 调用 move() 方法将窗口移动到屏幕的指定位置。
  • 第 5 步是窗口实例对象 window 调用 setWindowTitle() 方法设置窗口的标题。
  • 第 6 步是窗口实例对象 window 调用 show() 方法显示窗口,这时窗口是可见的。
  • 第 7 步是执行 QApplication 实例对象 app 的 exec()方法,开始窗口的事件循环,从而保证窗口一直处于显示状态。如果窗口上有其他控件,并为控件的消息编写了处理程序,则可以完成相应的动作。如果用户单击窗口右上角的关闭窗口按钮正常退出界面,或者因程序崩溃而非正常终止窗口的运行,都将引发关闭窗口(closeAllWindows())事件,这时 app 的方法 exec() 会返回一个整数,如果这个整数是 0 表示正常退出,如果非 0 表示非正常退出。请注意,当执行到 app 的 exec() 方法时,会停止后续语句的执行,直到所有可视化窗体都关闭(退出)后才执行后续的语句。
  • 第 8 步是调用系统模块的 exit() 方法,通知 Python 解释器程序已经结束,如果是 sys.exit(0) 状态,则 Python 认为是正常退出;如果不是 sys.exit(0) 状态,则 Python 认为是非正常退出。无论什么情况,sys.exit() 都会抛出一个异常 SystemExit,这时可以使用 try…except 语句捕获这个异常,并执行 except 中的语句。

3.3 QtDesigner实现前后端分离

​ 之前的代码将创建窗口和创建窗口控件的代码与控件的事件代码放到同一段程序中,如果程序非常复杂,控件很多,事件也很多,势必造成代码混杂,程序可读性差,编程效率也不高。为此可以把创建窗口控件的代码放到一个函数或类中,创建窗口的代码放到主程序中,从而使程序的可读性得到提高,也提高了编程效率。

3.3.1 函数定义界面

下面的代码将创建窗口控件的代码放到函数 setupUi() 中。setupUi() 函数的形参是窗口,在主程序中调用 setupUi() 函数,并把窗口实例作为实参传递给 setupUi() 函数,在 setupUi() 函数中往窗口上创建控件。

import sys

from PySide6.QtWidgets import QApplication, QWidget

def setupUi(window):
    # 1.设置窗口的尺寸
    window.resize(300, 150)
    # 2.移动窗口
    window.move(300, 300)
    # 3.设置窗口标题
    window.setWindowTitle("基于PySide的桌面应用程序")

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = QWidget()
    # 3.调用setupUi()函数,将窗口作为实参传递给setupUi()函数
    setupUi(window)
    # 4.展示窗口
    window.show()
    # 5.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

3.3.2 类定义界面

​ 下面的程序将创建窗口控件的代码定义到 MyUi 类的 setupUi() 函数中,各个控件是 MyUi 类中的属性,在主程序中用 MyUi 类实例化对象 ui,这样在主程序中就可以用 ui 引用窗口上的任何控件,在主程序中通过 ui 就可以修改控件的参数。

import sys

from PySide6.QtWidgets import QApplication, QWidget

class MyUi:
    def setupUi(self, window):
        # 1.设置窗口的尺寸
        window.resize(300, 150)
        # 2.移动窗口
        window.move(300, 300)
        # 3.设置窗口标题
        window.setWindowTitle("基于PySide的桌面应用程序")

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = QWidget()
    # 3.用MyUi类创建实例ui
    ui = MyUi()
    # 4.调用ui的setupUi()方法,并以窗口作为实参
    ui.setupUi(window)
    # 5.展示窗口
    window.show()
    # 6.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

3.3.3 界面用模块来定义

​ 如果一个界面非常复杂,创建界面控件的代码也就会很多,我们可以使用包和模块来管理,即在程序中创建界面控件的类 MyUi 可以单独存放到一个文件中,在使用的时候用 import 语句把 MyUi 类导入进来,实现控件代码与窗口代码的分离。

class MyUi:
    def setupUi(self, window):
        # 1.设置窗口的尺寸
        window.resize(300, 150)
        # 2.移动窗口
        window.move(300, 300)
        # 3.设置窗口标题
        window.setWindowTitle("基于PySide的桌面应用程序")

新建一个 py 文件,在这个 py 文件中用 from myUi import MyUi 语句把 MyUi 类导入进来,在主程序中用ui=MyUi()语句创建 MyUi 类的实例对象 ui,然后就可以用 ui 引用 myUi.py 文件中定义的控件。

import sys

from PySide6.QtWidgets import QApplication, QWidget

from myUi import MyUi

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = QWidget()
    # 3.用MyUi类创建实例ui
    ui = MyUi()
    # 4.调用ui的setupUi()方法,并以窗口作为实参
    ui.setupUi(window)
    # 5.展示窗口
    window.show()
    # 6.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

3.3.4 界面逻辑分离

​ 上面的代码中,可以把创建窗口和对控件操作的代码单独放到一个函数或类中,含有控件的代码称为界面代码,实现控件动作的代码称为逻辑或业务代码。

下面的代码创建 myWidget() 函数,在函数中用 widget=QWidget(parent) 语句创建 QWidget 类的实例对象 widget,这时首先执行的是 QWidget 类的初始化函数 __init__(),经过初始化后的对象成为真正窗口,注意 myWidget() 函数的返回值是窗口实例对象 widget。在主程序中调用 myWidget() 函数,得到返回值,然后显示窗口并进入消息循环。

import sys

from PySide6.QtWidgets import QApplication, QWidget

from myUi import MyUi

def myWidget(parent = None):
    # 1.创建QWidget类的对象,调用QWidget类的__init__()方法
    widget = QWidget(parent)
    # 2.实例化myUi.py文件中的MyUi类
    ui = MyUi()
    # 3.调用myUi类的setupUi()方法,以widget为实参传递给形参window
    ui.setupUi(widget)
    # 4.函数的返回值就是窗口实例对象
    return widget

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = myWidget()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

​ 上面代码中,只是用一个函数将界面与逻辑或业务分离,如果要对界面进行多种操作或运算,显然只用一个函数来定义是不够的。由于在类中可以定义多个函数,因而如果用类来代替上述函数,就可以极大地提高编程效率。为此可以把创建窗口和对控件操作的代码放到一个类中。

下面的代码创建一个类 MyWidget,其父类是窗口类 QWidget,在初始化函数 __init__() 中用 super() 函数调用父类的初始化函数,这时类 MyWidget 中的 self 将会是窗口类 QWidget 的实例对象,也就是一个窗口。在主程序中用类 MyWidget 实例化对象 myWindow,myWindow 就是 MyWidget 的 self 的具体值。myWindow可以显示出来,也可以进入事件循环。

import sys

from PySide6.QtWidgets import QApplication, QWidget

from myUi import MyUi

class MyWidget(QWidget):
    def __init__(self, parent=None):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__(parent)
        # 2.实例化myUi.py文件中的MyUi类
        ui = MyUi()
        # 3.调用myUi类的setupUi()方法,以self为实参传递给形参window
        ui.setupUi(self)

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = MyWidget()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

上面的程序属于单继承的方法,自定义类 MyWidget 只继承了 QWidget 类,在类 MyWidget 中还要定义类 MyUi 的实例对象。我们可以使用多继承的方法,自定义类 MyWidget 同时继承 QWidget 类和 MyUi 类,多继承无须再定义类 MyUi 的实例对象,类中的 self 既指 QWidget 类的窗口对象,也指 MyUi 的实例对象,即窗口上的控件。

import sys

from PySide6.QtWidgets import QApplication, QWidget

from myUi import MyUi

class MyWidget(QWidget, MyUi):
    def __init__(self, parent=None):
        # 1.调用父类的__init__()方法
        super().__init__(parent)
        # 2调用myUi类的setupUi()方法,以self为实参传递给形参window
        self.setupUi(self)

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = MyWidget()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

3.4 窗口的基本属性设置

​ 窗口包含一些基本的组成要素,包括对象名称、图标、标题、位置和背景等。这些要素可以通过 Qt Designer 中的 “属性编辑器” 窗口进行设计,也可以通过代码来实现。

QWidget 通用窗口常见的属性如下:

objectName          # 窗口的唯一标识,程序通过该属性调用窗口
geometry            # 该属性中可以设置窗口的宽度和高度
windowTitle         # 标题栏文本
windowIcon          # 窗口的标题栏图标
windowOpacity       # 窗口的透明度,取值范围为 0~1
windowModality      # 窗口样式,可选值有 NonModal、WindowModal 和 ApplicationModal
enable              # 窗口是否可用
minimumSize         # 窗口最小化时的大小,默认为 0×0
maximumSize         # 窗口最大化时的大小,默认为 16777215×16777215
palette             # 窗口的调色板,可以用来设置窗口的背景
font                # 设置窗口的字体,包括字体名称、字体大小、是否为粗体、是否为斜体、是否有下划线、是否有删除线等
cursor              # 窗口的鼠标样式
contextMenuPolicy   # 窗口的快捷菜单样式
acceptDrops         # 是否接受拖放操作
toolTip             # 窗口的提示文本
toolTipDuration     # 窗口的提示文本的显示间隔
statusTip           # 窗口的状态提示
whatsThis           # 窗口的 “这是什么” 提示
layoutDirection     # 窗口的布局方式,可选值有 LeftToRight、RightToLeft 和 LayoutDirectionAuto
autoFillBackground  # 是否自动填充背景
styleSheetlocale    # 设置窗口样式,可以用来设置窗口的背景
locale              # 设置窗口的国际化设置

QMainWindow 类新增的属性:

iconSize                        # 窗口标题栏图标的大小
toolButtonStyle                 # 窗口中的工具栏样式,默认值为 ToolButtonIconOnly,表示默认工具栏只是显示图标用户可以更改为只显示文本,或同时显示文本和图标
dockOptions                     # 停靠选项
unifiedTitleAndToolBarOnMac     # 在MacOS系统中是否可以定义标题和工具栏

QWidget 类的常用方法如下:

# 实例方法
setVisible(visible:bool) -> None                                    # 设置窗口是否可见
setWindowIcon(icon:QIcon) -> None                                   # 设置窗口图标
windowIcon() -> QIcon                                               # 获取窗口图标
setWindowIconText (arg__1:str) -> None                              # 设置窗口图标文本
windowIconText() -> str                                             # 获取窗口图标文本
windowTitle() -> str                                                # 获取窗口标题
isWindowModified() -> bool                                          # 获取窗口是否被修改过
setWindowModality(windowModality:Qt.WindowModality) -> None         # 设置窗口模态
isModal() -> bool                                                   # 获取窗口是否模态
setWindowOpacity(level:float) -> None                               # 设置窗口透明度
windowOpacity() -> float                                            # 获取窗口透明度
setWindowState(state:Qt.WindowStates) -> None                       # 设置窗口状态
windowState() -> Qt.WindowStates                                    # 获取窗口状态
activateWindow() -> None                                            # 激活窗口
isActiveWindow() -> bool                                            # 获取窗口是否激活

setMinimumHeight(minh:int) -> None                                  # 设置最小高度
setMinimumWidth(minw:int) -> None                                   # 设置最小宽度
setMinimumSize(minw:int, minh:int) -> None                          # 设置最小尺寸
setMinimumSize(minsize:QSize) -> None                               # 设置最小尺寸
setMaximumHeight(maxh:int) -> None                                  # 设置最大高度
setMaximumWidth(maxw:int) -> None                                   # 设置最大宽度
setMaximumSize(maxw:int, maxh:int) -> None                          # 设置最大尺寸
setMaximumSize(maxsize:QSize) -> None                               # 设置最大尺寸
setFixedHeight(h:int) -> None                                       # 设置固定高度
setFixedWidth(w:int) -> None                                        # 设置固定宽度
setFixedSize(w:int, h:int) -> None                                  # 设置固定尺寸
setFixedSize(size:QSize) -> None                                    # 设置固定尺寸

isMinimized() -> bool                                               # 获取窗口是否最小化
isMaximized() -> bool                                               # 获取窗口是否最大化
isFullScreen() -> bool                                              # 获取窗口是否全屏

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                                               # 移除窗口光标,使用父窗口光标

setUpdatesEnabled(enable:bool) -> None                              # 设置窗口更新
update(x:int, y:int, w:int, h:int) -> None                          # 更新窗口指定区域
update(arg__1:QRect) -> None                                        # 更新窗口指定区域

setLayout(layout:QLayout) -> None                                   # 设置窗口布局
layout() -> QLayout                                                 # 获取窗口布局
setLayoutDirection(direction:Qt.LayoutDirection) -> None            # 设置窗口布局方向

isWindow() -> bool                                                  # 获取是否为独立窗口
window() -> QWidget                                                 # 获取窗口

addAction(action:QAction) -> None                                   # 添加动作到窗口
addActions(actions:Sequence[QAction]) -> None                       # 添加动作到窗口
insertAction(before:QAction, action:QAction) -> None                # 在指定动作之前插入动作
insertActions(before:QAction, actions:Sequence[QAction]) -> None    # 在指定动作之前插入动作
actions() -> Sequence[QAction]                                      # 获取动作列表

repaint(x:int, y:int, w:int, h:int) -> None                         # 重绘窗口
repaint(arg__1:Union[QRegion, QPolygon, QRect]) -> None             # 重绘窗口

scroll(dx:int, dy:int) -> None                                      # 滚动窗口
scroll(dx:int, dy:int, arg__3:QRect) -> None                        # 滚动窗口

resize(w:int, h:int) -> None                                        # 重新设置窗口尺寸
resize(size:QSize) -> None                                          # 重新设置窗口尺寸
size() -> QSize                                                     # 获取窗口尺寸

move(x:int, y:int) -> None                                          # 移动窗口
move(arg__1:QPoint) -> None                                         # 移动窗口

pos() -> QPoint                                                     # 获取窗口左上角位置
x() -> int                                                          # 获取窗口左上角位置的x坐标
y() -> int                                                          # 获取窗口左上角位置的y坐标

frameGeometry() -> QRect                                            # 获取包含标题栏的外框架区域
frameSize() -> QSize                                                # 获取包含标题栏的外框架的尺寸

setGeometry(x:int, y:int, w:int, h:int) -> None                     # 设置窗口位置和尺寸
setGeometry(arg__1:QRect) -> None                                   # 设置窗口位置和尺寸
geometry() -> QRect                                                 # 获取窗口位置和尺寸


# 槽函数
show() -> None                                                      # 显示窗口,等同于setVisible(True)
setHidden(hidden:bool) -> None                                      # 设置窗口是否隐藏
hide() -> None                                                      # 隐藏窗口
raise_() -> None                                                    # 提升控件,放到控件栈的顶部
lower() -> None                                                     # 降低控件,放到控件栈的底部
setWindowTitle(title:str) -> None                                   # 设置窗口标题
setWindowModified(arg__1:bool) -> None                              # 设置窗口是否被修改过
showMinimized() -> None                                             # 最小化显示
showMaximized() -> None                                             # 最大化显示
showNormal() -> None                                                # 最小化显示或者最大化显示后回到正常显示
showFullScreen() -> None                                            # 全屏显示
update() -> None                                                    # 更新窗口
setFocus() -> None                                                  # 设置窗口焦点
  • show() 方法可以显示窗口,用 hide() 方法可以隐藏窗口,也可以用 setVisible(bool) 方法和 setHidden(bool) 方法设置窗口的可见性,用 isVisible()isHidden() 方法判断窗口是否可见,用 close() 方法可以关闭窗口。当窗口被关闭时,首先向这个窗口发送一个关闭事件 closeEvent(event:QCloseEvent),如果事件被接受,则窗口被隐藏;如果事件被拒绝,则什么也不做。如果创建窗口时用 setAttribute(Qt.WA_QuitOnClose,on=True) 方法设置了 Qt.WA_QuitOnClose 属性,则窗口对象会被析构(删除),大多数类型的窗口都默认设置了这个属性。close() 方法的返回值 bool 表示关闭事件是否被接受,也就是窗口是否真的被关闭了。
  • 独立窗口有正常、全屏、最大化、最小化几种状态,用 isMinimized() 方法判断窗口是否为最小化,用 isMaximized() 方法判断窗口是否为最大化,用 isFullScreen() 方法判断窗口是否为全屏,用 showMinimized() 方法设置以最小化方式显示窗口,用 showMaximized() 方法设置以最大化方式显示窗口,用 showFullScreen() 方法设置以全屏方式显示窗口,用 showNormal() 方法设置以正常方式显示窗口。另外用 setWindowState(Qt.WindowStates) 方法也可以设置窗口的状态,其中参数 Qt.WindowStates 可以取值如下:
Qt.WindowStates.WindowNoState     # 无标识,正常状态
Qt.WindowStates.WindowMinimized   # 最小化状态
Qt.WindowStates.WindowMaxmized    # 最大化状态
Qt.WindowStates.WindowFullScreen  # 全屏状态
Qt.WindowStates.WindowActive      # 激活状态

在主窗口中通常需要弹出一些需要进行设置或确认信息的对话框,在对话框没有关闭之前,通常不能对其他窗口进行操作,这就是窗口的模式。用 setWindowModality(Qt.WindowModality) 方法设置窗口的模式特性,其中枚举参数Qt.WindowModality可以取值如下:

Qt.WindowModality.NonModal            # 非模式,可以和程序的其他窗口进行交互操作
Qt.WindowModality.WindowModal         # 窗口模式,在未关闭当前窗口时,将阻止与该窗口的父辈窗口的交互操作
Qt.WindowModality.ApplicationModal    # 应用程序模式,在未关闭当前窗口时,将阻止窗口与任何其他窗口的交互操作

当有多个独立窗口同时存在时,只有一个窗口能够处于活跃状态。系统产生的键盘、鼠标等输入事件将被发送给处于活跃状态的窗口。一般来说,这样的窗口会被提升到堆叠层次的最上面,除非其他窗口有总在最上面的属性。用 activateWindow() 方法可以使窗口活跃,用 isActiveWindow() 方法可以查询窗口是否活跃。

处于激活状态的窗口才有可能处理键盘和鼠标等输入事件;反之,处于禁用状态的窗口不能处理这些事件。用 setEnabled(bool) 方法或 setDisabled(bool) 方法可以使窗口激活或失效,用 isEnabled() 方法可以查询窗口是否处于激活状态。

setLayout(QLayout) 方法可以设置窗口的布局,用 layout() 方法可以获取窗口的布局,用 setLayoutDirection(Qt.LayoutDirection) 方法可以设置布局的方向,其中参数 Qt.LayoutDirection 可以取值如下:

Qt.LayoutDirection.LeftToRight
Qt.LayoutDirection.RightToLeft
Qt.LayoutDirection.LayoutDirectionAuto

setAttribute(Qt.WidgetAttribute,on=True) 方法可以设置窗口的属性,用 testAttribute(Qt.WidgetAttribute) 方法可以测试是否设置了某个属性,其中参数 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      # 用户自定义快捷菜单,右击鼠标时,发射customContextMenuRequest(QPoint)信号
Qt.ContextMenuPolicy.PreventContextMenu     # 鼠标右键事件交给控件的mousePressEvent()和mouseReleaseEvent()函数进行处理

QWidget 类的常用信号如下:

customContextMenuRequested(pos:QPoint)          # 通过setContextMenuPolicy(Qt.CustomContextMenu)方法设置快捷菜单时自定义菜单,此时右击鼠标时发射信号
windowIconChanged(icon:QIcon)                   # 窗口图标改变时发射信号
windowIconTextChanged(iconText:str)             # 窗口标题改变时发射信号
windowTitleChanged(title:str)                   # 窗口标题改变时发射信号
from PySide6.QtGui import QIcon, QPixmap

class MyUi:
    def setupUi(self, window):
        # 1.设置窗口的唯一标识
        window.setObjectName("MainWindow")

        # 2.设置窗口对象的位置和大小
        # 前两个值指定窗口位置,后两个值指定窗口大小
        window.setGeometry(300, 300, 700, 500)

        # 3.设置窗口图标
        icon = QIcon()
        icon.addPixmap(QPixmap("1.ico"))
        window.setWindowIcon(icon)

        # 4.设置窗口标题
        window.setWindowTitle("基于PySide6的桌面应用程序")

        # 5.设置窗口的背景
        # 设置背景颜色
        # w.setStyleSheet("#MainWindow{background-color:pink}")
        window.setStyleSheet("background-color:pink")

        # 6.设置窗口透明图
        window.setWindowOpacity(0.8)

3.5 设置窗口样式

​ 在 PySide6 中,使用 setWindowFlags(PySide6.QtCore.Qt.WindowFlags) 设置窗口的样式。其中,PySide6.QtCore.Qt.WindowFlags 参数表示要设置的窗口样式,它的取值范围内为两种类型。

PySide 的基本窗口类型及其说明

Qt.Widget       # 默认窗口,有最大化、最小化和关闭按钮
Qt.Window       # 普通窗口,有最大化、最小化和关闭按钮
Qt.Dialog       # 对话框窗口,有关闭按钮
Qt.Popup        # 无边框的弹出窗口
Qt.ToolTip      # 无边框的提示窗口,没有任务栏
Qt.SplashScreen # 无边框的闪屏窗口,没有任务栏
Qt.SubWindow    # 子窗口,窗口没有按钮,但有标题

自定义顶层窗口外观及其说明

Qt.MSWindowsFixedSizeDialogHint     # 无法调整窗口的大小
Qt.FramelessWindowHint              # 无边框窗口
Qt.CustomizeWindowHint              # 有边框但无标题栏和按钮,不能移动和拖动的窗口
Qt.WindowTitleHint                  # 添加标题栏和一个关闭按钮的窗口
Qt.WindowSystemMenuHint             # 添加系统目录和一个关闭按钮的窗口
Qt.WindowMaximizeButtonHint         # 激活最大化按钮的窗口
Qt.WindowMinimizeButtonHint         # 激活最小化按钮的窗口
Qt.WindowMinMaxButtonsHint          # 激活最小化和最大化按钮的窗口
Qt.WindowCloseButtonHint            # 添加一个关闭按钮的窗口
Qt.WindowContextHelpButtonHint      # 添加向对框框一样的问号和关闭按钮的窗口
Qt.WindowStaysOnTopHint             # 使窗口始终处于顶层位置
Qt.WindowStaysOnBottomHint          # 使窗口始终处于底层位置
from PySide6.QtCore import Qt
from PySide6.QtGui import QIcon, QGuiApplication

class MyUi:
    def setupUi(self, window):
        # 1.设置窗口的唯一标识
        window.setObjectName("MainWindow")

        # 2.设置窗口对象大小
        window.resize(700, 500)

        # 3.设置窗体居中显示
        screen_size = QGuiApplication.primaryScreen().size()
        size = window.size()
        window.move((screen_size.width() - size.width()) / 2, (screen_size.height() - size.height()) / 2)

        # 4.设置窗口图标
        icon = QIcon("1.ico")
        window.setWindowIcon(icon)

        # 5.设置窗口标题
        window.setWindowTitle("基于PySide的桌面应用程序")

        # 6.设置窗口的背景
        # 设置背景图片,如果使用 background-image 图片会平铺显示
        # w.setStyleSheet("#MainWindow{border-image:url(1.jpeg)}")
        window.setStyleSheet("border-image:url(1.jpeg)")

        # 7.设置窗口样式
        window.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint | Qt.WindowStaysOnTopHint)

参考链接:https://www.cnblogs.com/kurome/p/17779267.html

4.信号和槽

信号(signal)与 (slot)是 Qt 的核心机制,也是进行 PySide6 编程时,对象与对象之间通信的基础。在 PySide6 中,每一个 QObject 对象(包括各种窗口控件)都支持信号与槽机制。通过信号与槽的关联,就可以实现对象之间的通信。

信号 是指从 QObject 类继承的控件(窗口、按钮、文本框、列表框等)在某个动作下或状态发生改变时发出的一个指令或一个信息。 是系统对控件发出的信号进行的响应,或者产生的动作,通常用函数来定义系统的响应或动作。当信号发射时,连接的 槽函数(方法)将会自动执行。在 PySide6 中,信号与槽是通过对象的 signal.connect() 方法进行连接的。信号与槽的关系可以是一对一,也可以是多对多,即一个信号可以关联多个槽函数,一个槽函数也可以接收多个信号。

PySide6 中信号与槽的主要特点如下:

  • 一个信号可以连接多个槽;
  • 一个槽可以监听多个信号;
  • 信号与信号之间可以互联;
  • 信号与槽的连接可以跨线程;
  • 信号与槽的连接即可以是同步的,也可以是异步的;
  • 信号的参数可以是任何的 Python 类型;

4.1 信号与槽的使用

控件.信号.connect(槽函数)

def 槽函数():
    pass
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton, QMessageBox

class MyWidget(QWidget):
    def __init__(self):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__()
        # 2.调用setupUi()方法初始化页面
        self.setupUi()

    def setupUi(self):
        # 1.设置窗口对象大小
        self.resize(700, 500)
        # 2.创建按钮控件
        pubshButton = QPushButton(self)
        # 3.按钮控件的显示文本
        pubshButton.setText("退出")
        # 4.将按钮的clicked信号与自定义的槽函数关联
        pubshButton.clicked.connect(self.show_message)

    def show_message(self):
        # 使用information()方法弹出信息提示框
        # 第一个参数是窗口对象,表示该对话框所属的窗口
        # 第二个参数是对话框的标题
        # 第三个参数是对话框的提示文本
        # 第四个参数是对话框中操作按钮,多个按钮之间用|分开
        select = QMessageBox.information(self, "提示框", "你是否要退出呢?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
        if select == QMessageBox.StandardButton.Yes:
            sys.exit(app.exec())

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = MyWidget()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

4.2 自定义信号

​ 除了可以用控件的内置信号外,还可以自定义信号。自定义信号可以不带参数,也可以带参数,可以带 1 个参数,也可以带多个参数。参数类型是任意的,参数类型需要在定义信号时进行声明。自定义信号通常需要在类属性位置用 Signal 类来创建,使用 Signal 前需要用 from PySide6.QtCore import Signal 语句导入 Signal 类。需要注意的是,只有继承自 QObject 的类才可以定义信号

其中,signalName信号名称Signal() 用于 创建信号实例对象type信号发送时附带的数据类型,这里数据类型不是形参也不是实参,只是类型的声明,参数类型任意,需根据实际情况确定。

定义一个信号后,信号就有 连接 connect()发送 emit()断开 disconnect() 属性,需要注意的是,只有从 QObject 继承的类才可以定义信号。

from PySide6.QtCore import QObject, Signal

class SignalDefinition(QObject):
    s1 = Signal()                               # 创建无参数的信号
    s2 = Signal(int)                            # 创建带整数的信号
    s3 = Signal(float)                          # 创建带浮点数的信号
    s4 = Signal(str)                            # 创建带字符串的信号
    s5 = Signal(int, float, str)                # 创建带整数、浮点数和字符串的信号
    s6 = Signal(list)                           # 创建带列表的信号
    s7 = Signal(dict)                           # 创建带字典的信号

    def __init__(self, parent=None):
        super().__init__(parent)

        # 信号与槽的连接
        self.s1.connect(self.slot1)
        self.s2.connect(self.slot2)
        self.s3.connect(self.slot3)
        self.s4.connect(self.slot4)
        self.s5.connect(self.slot5)
        self.s6.connect(self.slot6)
        self.s7.connect(self.slot7)

        # 提交信号
        self.s1.emit()
        self.s2.emit(10)
        self.s3.emit(11.11)
        self.s4.emit("你好,世界!")
        self.s5.emit(10, 11.11, "你好,世界!")
        self.s6.emit([10, 11.11, "你好,世界!"])
        self.s7.emit({"1": "Sakura", "2": "Shana"})

    def slot1(self):
        print("s1 emit")

    def slot2(self, value):
        print("s2 emit int: ", value)

    def slot3(self, value):
        print("s3 emit float: ", value)

    def slot4(self, string):
        print("s4 emit string: ", string)

    def slot5(self, value1, value2, string):
        print("s5 emit many values: ", value1, value2, string)

    def slot6(self, list_value):
        print("s6 emit list: ", list_value)

    def slot7(self, dict_value):
        print("s7 emit dict: ", dict_value)

if __name__ == "__main__":
    signalTest = SignalDefinition()

参考链接:https://www.cnblogs.com/kurome/p/17783223.html

5.GUI编程常用类

5.1 坐标点类(QPoint,QPointF)

​ 电脑屏幕的坐标系的原点在左上角,从左到右是 x 轴方向,从上往下是 y 轴方向。要定位屏幕上的一个点的位置,需要用到 QPoint 类或 QPointF 类,这两个类的区别是 QPoint整数 定义 x 和 y 值,QPointF 用浮点数定义 x 和 y值。QPoint 类和 QPointF 类在 QtCore 模块中,使用前需用 from PySide6.QtCore import QPoint, QPointF 语句导入到当前程序中。

用 QPoint 和 QPointF 类定义坐标点实例的方法如下所示,其中 xpos 和 ypos 分别表示 x 和 y 坐标。

QPoint()
QPoint(xpos:int, ypos:int)

QPointF()
QPointF(xpos:float, ypos:float)
QPointF(point:QPoint)

QPoint 类的常用方法及其说明如下:

# 实例方法
x() -> int                                  # 获取x坐标值
y() -> int                                  # 获取y坐标值
setX(x:int) -> None                         # 设置x坐标值
setY(y:int) -> None                         # 设置y坐标值

toTuple() -> tuple[int, int]                # 返回元组(x,y)
isNull() -> bool                            # 如果x=y=0,则返回True
manhattanLength() -> int                    # 返回x和y绝对值的和
transposed() -> QPoint                      # 返回一个新的QPoint,其x和y值交换
toPointF() -> QPointF                       # 返回一个QPointF对象

# 静态方法
dotProduct(p1:QPoint, p2:QPoint) -> int     # 返回两个点的点乘,x1*x2+y1*y2

​ QPointF 类的方法与 QPoint 类的方法类似,只是它的参数的参数类型为 float,QPointF 类中没有 toPointF() 方法,它有一个 toPoint() 方法,用来四舍五入将 QPointF 转换为 QPoint。

QPoint 或 QPointF 可以当作二维向量,用于加减运算,也可以与一个整数或浮点数相乘或相除,还可以逻辑判断。

from PySide6.QtCore import QPoint, QPointF

if __name__ == "__main__":
    p1 = QPoint(-3, 4)
    p2 = QPointF(5.5, 8.3)

    p3 = p1.toPointF()
    p4 = p2.toPoint()

    p5 = p1 * 3
    p6 = p3 + p2

    print(p1.toTuple())                     # (-3, 4)
    print(p1 == p3)                         # (-3, 4)

    print(p5.x(), p5.y())                   # -9 12
    print(p6.x(), p6.y())                   # 2.5 12.3

    print(QPoint.dotProduct(p1, p4))        # 14
    print(QPointF.dotProduct(p2, p3))       # 16.700000000000003

5.2 尺寸类(QSize,QSizeF)

​ 一个控件或窗口有长度和高度属性,长度高度 可以用 QSize 类或 QSizeF 类来定义。QSize 类和 QSizeF 类在 QtCore 模块中,使用前需用 from PySide6.QtCore import QSize, QSizeF 语句导入到当前程序中。

用 QSize 和 QSizeF 定义尺寸实例的方法如下,其中 w 和 h 分别表示宽度或高度,QSize 用整数定义,QSizeF 用浮点数定义。

QSize()
QSize(w:int, h:int)

QSizeF()
QSizeF(w:float, h:float)
QSizeF(size:QSizze)

QSize 和 QSizeF 的方法基本相同,QSizeF 的常用方法如下。

width() -> float                                                # 获取宽度
height() -> float                                               # 获取高度
setWidth(w:float) -> None                                       # 设置宽度
setHeight(h:float) -> None                                      # 设置高度

shrunkBy(m:Union[QMargins,QMarginsF]) -> QSizeF                 # 在原QSizeF基础上根据页边距收缩得到新的QSizeF
grownBy(m:Union[QMargins,QMarginsF]) -> QSizeF                  # 在原QSizeF基础上根据页边距扩充得到新的QSizeF

boundedTo(arg__1:Union[QSize,QSizeF]) -> QSizeF                 # 新QSizeF的宽度和高度是自己和参数中值小的那个
expandedTo(arg__1:Union[QSize,QSizeF]) -> QSizeF                # 新QSizeF的宽度和高度是自己和参数中值大的那个

toTuple() -> tuple[float,float]                                 # 返回元组(width,height)

isEmpty() -> bool                                               # 当宽度和高度有一个小于等于0时,返回True
isNull() -> bool                                                # 当宽度和高度都为0时,返回True
isValid() -> bool                                               # 当宽度和高度都大于0时,返回True

transpose() -> None                                             # 交换width和height
transposed() -> QSizeF                                          # 返回一个新的QSizeF,交换width和height

scale(w:float, h:float, mode:Qt.AspectRatioMode) -> None        # 根据高度和宽度的比值参数Qt.AspectRatioMode,重新设置原QSizeF的宽度和高度
scale(s:QSizeF, mode:Qt.AspectRatioMode) -> None                # 根据高度和宽度的比值参数Qt.AspectRatioMode,重新设置原QSizeF的宽度和高度
scaled(w:float, h:float, mode:Qt.AspectRatioMode) -> QSizeF     # 返回调整后的新QSizeF
scaled(s:QSizeF, mode:Qt.AspectRatioMode) -> QSizeF             # 返回调整后的新QSizeF
toSize() -> QSize                                               # 将QSizeF转换为QSize   

其中 scale(width:float,height:float,Qt.AspectRatioMode) 方法中,Qt.AspectRatioMode 取值如下:

  • Qt.IgnoreAspectRatio(不保持比例关系,缩放后的 QSizeF 尺寸是 (width,height));
  • Qt.KeepAspectRatio(保持原比例关系,缩放后的 QSizeF 在 (width,height) 内部尽可能大);
  • Qt.KeepAspectRatioByExpanding(保持原比例关系,缩放后的 QSizeF 在 (width,height) 外部尽可能小),参数值不同,返回的值也不同;

QSize 和 QSizeF 类也可以进行加减乘除运算和逻辑运算。

from PySide6.QtCore import QSize, QSizeF
from PySide6.QtCore import Qt, QMargins

if __name__ == "__main__":
    s1 = QSize(5, 6)
    s2 = QSizeF(8, 10)

    s3 =  s2 - s1
    s4 = s1 * 3

    print(s3.width(), s3.height())          # 3.0 4.0
    print(s4.width(), s4.height())          # 15 18

    margin = QMargins(1, 2, 3, 4)
    s5 = s2.shrunkBy(margin)
    print(s5.width(), s5.height())          # 4.0 4.0

    s6 = s1.scaled(10, 20, Qt.AspectRatioMode.IgnoreAspectRatio)
    print(s6.width(), s6.height())          # 10 20

    s7 = s1.scaled(10, 20, Qt.AspectRatioMode.KeepAspectRatio)
    print(s7.width(), s7.height())          # 10 12

    s8 = s1.scaled(10, 20, Qt.AspectRatioMode.KeepAspectRatioByExpanding)
    print(s8.width(), s8.height())          # 16 20

5.3 矩形框类(QRect, QRectF)

​ 矩形框可以定义一个矩形区域,含有 QPoint 和 QSize 信息的类,矩形框的左上角是 QPoint 的信息,矩形框的宽度和高度是 QSize 信息。对于一个控件,在窗口中有位置、宽度和高度信息,控件的位置可以通过其左上角的位置确定,控件的位置、宽度和高度都可以通过矩形框类来定义。矩形框类 分为 QRectQRectF 两种,它们在 QtCore 模块中,使用前需要用 from PySide6.QtCore import QRect, QRectF 语句导入到当前程序中。

用 QRect 或 QRectF 类来定义矩形框实例对象,可以采用以下几种方法,其中 QRect 用整数定义,QRectF 用浮点数定义。

x() -> int                                                      # 返回左上角的x值
y() -> int                                                      # 返回左上角的y值
setX(x:int) -> None                                             # 设置左上角的x值
setY(y:int) -> None                                             # 设置左上角的y值

left() -> int                                                   # 返回左边x值
right() -> int                                                  # 返回右边x值
top() -> int                                                    # 返回上边y值
bottom() -> int                                                 # 返回下边y值
setLeft(pos:int) -> None                                        # 设置左边pos值
setRight(pos:int) -> None                                       # 设置右边pos值
setTop(pos:int) -> None                                         # 设置上边pos值
setBottom(pos:int) -> None                                      # 设置下边pos值
moveLeft(pos:int) -> None                                       # 移动左边到pos值
moveRight(pos:int) -> None                                      # 移动右边到pos值
moveTop(pos:int) -> None                                        # 移动上边到pos值
moveBottom(pos:int) -> None                                     # 移动下边到pos值

topLeft() -> QPoint                                             # 获取左上角的QPoint
topRight() -> QPoint                                            # 获取右上角的QPoint
bottomLeft() -> QPoint                                          # 获取左下角的QPoint   
bottomRight() -> QPoint                                         # 获取右下角的QPoint
setTopLeft(p:QPoint) -> None                                    # 设置左上角的位置
setTopRight(p:QPoint) -> None                                   # 设置右上角的位置
setBottomLeft(p:QPoint) -> None                                 # 设置左下角的位置
setBottomRight(p:QPoint) -> None                                # 设置右下角的位置
moveTopLeft(p:QPoint) -> None                                   # 移动左上角到p  
moveTopRight(p:QPoint) -> None                                  # 移动右上角到p
moveBottomLeft(p:QPoint) -> None                                # 移动左下角到p
moveBottomRight(p:QPoint) -> None                               # 移动右下角到p

center() -> QPoint                                              # 获取中心点的QPoint
moveCenter(p:QPoint) -> None                                    # 移动中心点到p

getCoords() -> tuple[int, int, int, int]                        # 获取左上角和右下脚位置的坐标元组(x1,y1,x2,y2)
setCoords(x1:int, y1:int, x2:int, y2:int) -> None               # 设置左上角位置(x1,y1)右下脚位置(x2,y2)

height() -> int                                                 # 返回高度
width() -> int                                                  # 返回宽度
setWidth(w:int) -> None                                         # 设置宽度
setHeight(h:int) -> None                                        # 设置高度

size() -> QSize                                                 # 返回宽度和高度
setSize(s:QSize) -> None                                        # 设置宽度和高度

getRect() -> tuple[int, int, int, int]                          # 获取矩形框的左上角坐标和宽高的元组(x1,y1,w,h)
setRect(x:int, y:int, w:int, h:int) -> None                     # 设置矩形框的左上角的位置及其宽度和高度

isEmpty() -> bool                                               # 当宽度和高度有一个小于等于0时,返回True
isNull() -> bool                                                # 当宽度和高度都是0时,返回True
isValid() -> bool                                               # 当宽度和高度都大于0时,返回True

adjust(x1:int, y1:int, x2:int, y2:int) -> None                  # 调整位置,调整后的位置是在原左上角的x和y分别加上x1和y1,右下角的位置x和y分别加上x2和y2
adjusted(x1:int, y1:int, x2:int, y2:int) -> QRect               # 调整位置,返回一个新的QRect对象,调整后的位置是在原左上角的x和y分别加上x1和y1,右下角的位置x和y分别加上x2和y2

moveTo(x:int, y:int) -> None                                    # 左上角移动到(x,y)位置
moveTo(p:QPoint) -> None                                        # 左上角移动到p位置

intersects(r:QRect) -> bool                                     # 返回两个矩形的公共交叉矩形
intersected(other:QRect) -> QRect                               # 判断两个矩形是否有公共交叉矩形
united(other:QRect) -> QRect                                    # 返回由两个矩形的边形成的新矩形

translate(dx:int, dy:int) -> None                               # 矩形框整体平移dx、dy
translate(p:QPoint) -> None                                     # 矩形框整体平移p.x()和p.y()
translated(dx:int, dy:int) -> QRect                             # 返回平移dx和dy后的新QRect对象
translated(p:QPoint) -> QRect                                   # 返回平移p.x()和p.y()后的新QRect对象

transposed() -> QRect                                           # 返回宽度和高度对换后的新QRect对象

5.4 页边距类(QMargins,QMarginsF)

页边距类 QMarginsQMarginsF 通常应用于布局、窗口和打印中,设置布局控件或窗口内的工作区距边框的左边、顶部、右边和底部的距离,或者在打印中设置打印区域距纸张四个边的距离。用布局或窗口的 setContentsMargins(QMargins) 方法可设置页边距。

页边距示意图

QMargins 定义的页边距是整数,QMarginsF 定义的页边距是浮点数。用 QMargins 和 QMarginsF 创建页边距对象的方法如下所示。

QMargins()
QMargins(margins:QMargins)
QMargins(left:int, top:int, right: int, bottom:int)

QMarginsF()
QMarginsF(QMarginsF:Union[QMarginsF,QMargins])
QMarginsF(left:float, top:float, right:float, bottom:float)
left() -> int                       # 获取左边距
right() -> int                      # 获取右边距
top() -> int                        # 获取顶边距
bottom() -> int                     # 获取底边距
setLeft(left:int) -> None           # 设置左边距
setRight(right:int) -> None         # 设置右边距
setTop(top:int) -> None             # 设置顶边距
setBottom(bottom:int) -> None       # 设置底边距

isNull() -> bool                    # 判断页边距是否为空

toMarginsF() -> QMarginsF           # 转换为QMarginsF对象

5.5 字体类(QFont)

字体类 QFont 可以设置界面控件上显示的字体,字体属性包括字体名称、字体尺寸、粗体字、倾斜字、上/下划线、删除线等。如果指定的字体在使用时没有对应的字体文件,Qt 将自动选择最接近的字体。如果要显示的字符在字体中不存在,则字符会被显示为一个空心方框。

字体类在 QtGui 模块中,使用前需要用 from PySide6.QtGui import QFont 语句把字体类导入进来。用字体类定义字体实例对象的方法如下。

QFont(family:str, pointSize:int=-1, weight:int=-1, italic:bool=False)
QFont(families:list, pointSize:int=-1, weight:int=-1, italic:bool=False)

其中,参数 familiesfamily字体名称pointSize字体尺寸,取值为负值或 0 时,字体尺寸与系统有关,通常是 12 点;weight字体粗细程度italic斜体

QFont 类常用方法如下:

family() -> str                                                     # 获取字体名称
families() -> list                                                  # 获取字体名称
setFamily(arg__1:str) -> None                                       # 设置字体名称
setFamilies(arg__1:list) -> None                                    # 设置字体名称

bold() -> bool                                                      # 获取是否粗体,如果weight()的值大于QFont.Medium,则返回True
setBold(arg__1:bool) -> None                                        # 设置是否粗体
italic() -> bool                                                    # 获取是否斜体
setItalic(arg__1:bool) -> None                                      # 设置是否斜体

weight() -> QFont.Weight                                            # 获取字体权重
setWeight(weight:QFont.Weight) -> None                              # 设置字体权重

overline() -> bool                                                  # 获取是否有上划线
setOverline(arg__1:bool) -> None                                    # 设置是否有上划线
underline() -> bool                                                 # 获取是否有下划线
setUnderline(arg__1:bool) -> None                                   # 设置是否有下划线
strikeOut() -> bool                                                 # 获取是否有删除线
setStrikeOut(arg__1:bool) -> None                                   # 设置是否有删除线

style() -> QFont.Style                                              # 获取字体样式
setStyle(style:QFont.Style) -> None                                 # 设置字体样式

fixedPitch() -> bool                                                # 获取是否是固定宽度字体
setFixedPitch(arg__1:bool) -> None                                  # 设置固定宽度,即设置是否是固定宽度字体
kerning() -> bool                                                   # 获取是否开启字体间距
setKerning(arg__1:bool) -> None                                     # 设置是否开启字体间距
letterSpacing() -> float                                            # 获取字母间距
setLetterSpacing(type:QFont.SpacingType, spacing:float) -> None     # 设置字母间距
wordSpacing() -> float                                              # 获取单词间距
setWordSpacing(spacing:float) -> None                               # 设置单词间距


capitalization() -> QFont.capitalization                            # 获取字母大小写
setCapitalization(arg__1:QFont.capitalization) -> None              # 设置字母大小写

pixelSize() -> int                                                  # 获取像素尺寸
setPixelSize(arg__1:int) -> None                                    # 设置像素尺寸
pointSize() -> int                                                  # 获取点尺寸   
setPointSize(arg__1:int) -> None                                    # 设置点尺寸
pointSizeF() -> float                                               # 获取点尺寸
setPointSizeF(arg__1:float) -> None                                 # 设置点尺寸

stretch() -> int                                                    # 获取拉伸百分比
setStretch(arg__1:int) -> None                                      # 设置拉伸百分比

toString() -> str                                                   # 将字体属性以字符串形式输出
fromString(arg__1:str) -> bool                                      # 从字符串中读取属性,成功则返回True
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QFont

class FontTest(QWidget):
    def __init__(self):
        # 调用父类QWidget类的__init__()方法
        super().__init__()
        # 设置窗口尺寸
        self.setGeometry(200, 200, 800, 600)

        self.create_font()
        self.create_lables()
        self.get_label_font()

    def create_font(self):
        self.fonts = list()
        self.font_name = ("宋体", "仿宋", "黑体", "楷体", "隶书", "幼圆", "华文中宋", "方正舒体", "华文黑体", "Times New Roman")
        for i in self.font_name:
            f = QFont()
            f.setPointSizeF(25.5)
            f.setFamily(i)
            print(i)
            self.fonts.append(f)

        self.fonts[0].setBold(True)
        self.fonts[1].setItalic(True)
        self.fonts[2].setStrikeOut(True)
        self.fonts[3].setOverline(True)
        self.fonts[4].setUnderline(True)
        self.fonts[5].setCapitalization(QFont.Capitalization.AllUppercase)
        self.fonts[6].setWeight(QFont.Weight.Thin)
        self.fonts[7].setWordSpacing(50)
        self.fonts[8].setStretch(70)
        self.fonts[9].setPixelSize(50)

    def create_lables(self):
        self.labels = list()
        string = "Nice to Meet You! 很高兴认识你!"
        for i in range(len(self.font_name)):
            label = QLabel(self)
            label.setGeometry(0, 50 * i, 800, 70)
            label.setText(f"{str(i)} : {string}")
            label.setFont(self.fonts[i])
            self.labels.append(label)


    def get_label_font(self):
        print("字体信息")
        template = "Label {}, family: {}, Bold: {}, Italic: {}, StrikeOut: {}, OverLine: {}, UnderLine: {}, " \
            "Capitalization: {}, Weigth: {}, WordSpacing: {}, Stretch: {}, PixeSize: {}, PointSize: {}"
        j = 0
        for i in self.labels:
            f = i.font()
            print(template.format(j, f.family(), f.bold(), f.italic(), f.strikeOut(), f.overline(), f.underline(),
                                  f.capitalization(), f.weight(), f.wordSpacing(), f.stretch(), f.pixelSize(), f.pointSize()))

            j += 1

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.获取程序默认的字体
    font = app.font()
    # 3.设置字体名称
    font.setFamily("Helvetica[Cronyx]")
    # 4.设置程序默认字体
    app.setFont(font)
    # 5.创建一个窗口
    window = FontTest()
    # 6.展示窗口
    window.show()
    # 7.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

image-20240614093201483

5.6 颜色类(QColor)

PySide6 的颜色类是 QColor,颜色可以用 RGB(红,red;绿,green;蓝,blue)值来定义,还可以用 HSV(色相,hue;饱和度,saturation;值,value)值、CMYK(青色,cyan;品红,magenta;黄色,yellow;黑色,black)值或 HSL(色相,hue;饱和度,saturation;亮度,lightness)值来定义。

​ RGB 和 HSV 可以用于电脑屏幕的颜色显示,红绿蓝三种颜色的值都为0 ~ 255,值越大表示这种颜色的分量越大,HSV 中 H 的取值为0 ~ 359,S 和 V 的取值都为 0 ~ 255。除了定义红绿蓝 3 种颜色成分外,通常还需要定义 alpha 通道值,表示颜色的透明度。alpha 通道的取值也是0 ~ 255,值越大表示越不透明。

QColor()
QColor(name:str)
QColor(color:QtCore.Qt.GlobalColor)
QColor(r:int, g:int, b:int, a:int=255)
QColor(rgb:int)
QColor(spec:QColor.Spec, a1:int, a2:int, a3:int, a4:int, a5:int=0)

其中,QColor(name:str)name 是 颜色名称,例如 'Blue'、'Beige'、'LightPink'。颜色值还可以用 RGB 字符串RGBA 字符串 来定义,RGB 字符串格式是 "#RRGGBB",RGBA 字符串 格式是 “#RRGGBBAA”,其中 RR、GG 和 BB分别是用十六进制表示的红、绿、蓝颜色的值,AA 是 alpha 通道的值,例如 “#ff000000” 表示红色。

# 实例方法
red() -> int                                                                # 获取RGB中的R值
redF() -> float                                                             # 获取RGB中的R值
setRed(red:int) -> None                                                     # 设置RGB中的R值
setRedF(red:float) -> None                                                  # 设置RGB中的R值

green() -> int                                                              # 获取RGB中的G值
greenF() -> float                                                           # 获取RGB中的G值  
setGreen(green:int) -> None                                                 # 设置RGB中的G值
setGreenF(green:float) -> None                                              # 设置RGB中的G值

blue() -> int                                                               # 获取RGB中的B值
blueF() -> float                                                            # 获取RGB中的B值
setBlue(blue:int) -> None                                                   # 设置RGB中的B值
setBlueF(blue:float) -> None                                                # 设置RGB中的B值

alpha() -> int                                                              # 获alpha通道值
alphaF() -> float                                                           # 获取alpha通道值
setAlpha(alpha:int) -> None                                                 # 设置alpha通道值
setAlphaF(alpha:float) -> None                                              # 设置alpha通道值

rgb() -> int                                                                # 获取RGB值
rgba() -> int                                                               # 获取RGBA值
getRgb() -> tuple[int, int, int, int]                                       # 获取R、G、B、A值
getRgbF() -> tuple[float, float, float, float]                              # 获取R、G、B、A值
setRgb(rgb:int) -> None                                                     # 设置RGB值
setRgba(rgba:int) -> None                                                   # 设置RGBA值
setRgb(r:int, g:int, b:int, a:int=255)                                      # 设置R、G、B、A值
setRgbF(r:float, g:float, b:floaat, a:float=1.0)                            # 设置R、G、B、A值

getHsl() -> tuple[int, int, int, int]                                       # 获取H、S、L和A值
getHslF() -> tuple[float, float, float, float]                              # 获取H、S、L和A值
setHsl(h:int, s:int, l:int, a:int=255) -> None                              # 设置HSL值
setHslF(h:float, s:float, l:float, a:float=1.0) -> None                     # 设置HSL值

getHsv() -> tuple[int, int, int, int]                                       # 获取H、S、V和A值
getHsvF() -> tuple[float, float, float, float]                              # 获取H、S、V和A值
setHsv(h:int, s:int, v:int, a:int=255) -> None                              # 设置HSV值
setHsvF(h:float, s:float, v:float, a:float=1.0) -> None                     # 设置HSV值

getCmyk() -> tuple[int, int, int, int, int]                                 # 获取C、M、Y、K和A值
getCmykF() -> tuple[float, float, float, float, float]                      # 获取C、M、Y、K和A值
setCmyk(c:int, m:int, y:int, k:int, a=255) -> None                          # 设置CMYK值
setCmykF(c:float, m:float, y:float, k:float, a:float=1.0) -> None           # 设置CMYK值

name(format=QColor.NameFormat.HexRgb) -> str                                # 获取颜色的名称或十六进制值
setNamedColor(name:str) -> None                                             # 设置颜色的名称或十六进制值

convertTo(colorSpec:QColor.Spec) -> QColor                                  # 获取指定格式的颜色副本
spec() -> QColor.Spec                                                       # 获取颜色的格式

isValid() -> bool                                                           # 判断颜色是否有效

toCmyk() -> QColor                                                          # 转换为CMYK颜色
toHsl() -> QColor                                                           # 转换为HSL颜色
toHsv() -> QColor                                                           # 转换为HSV颜色
toRgb() -> QColor                                                           # 转换为RGB颜色

# 静态方法
fromCmyk(c:int, m:int, y:int, k:int, a:int=255) -> QColor                   # 从C、M、Y、K和A值创建CMYK颜色
fromCmykF(c:float, m:float, y:float, k:float, a:float=1.0) -> QColor        # 从C、M、Y、K和A值创建CMYK颜色
fromHsl(h:int, s:int, l:int, a:int=255) -> QColor                           # 从H、S、L和A值创建HSL颜色
fromHslF(h:float, s:float, l:float, a:float=1.0) -> QColor                  # 从H、S、L和A值创建HSL颜色
fromHsv(h:int, s:int, v:int, a:int=255) -> QColor                           # 从H、S、V和A值创建HSV颜色
fromHsvF(h:float, s:float, v:float, a:float=1.0) -> QColor                  # 从H、S、V和A值创建HSV颜色
fromRgb(r:int, g:int, b:int, a:int=255) -> QColor                           # 从R、G、B、A值创建RGB颜色
fromRgbF(r:float, g:float, b:float, a:float=1.0) -> QColor                  # 从R、G、B、A值创建RGB颜色
fromRgb(rgb:int) -> QColor                                                  # 从RGB值创建RGB颜色
fromRgba(rgba:int) -> QColor                                                # 从RGBA值创建RGB颜色

isValidColor(name:str) -> bool                                              # 判断用文本表示的颜色值是否有效

用 RGB 来定义颜色时,一些 RGB 值与颜色名称的对应关系如下:

QColor(255, 0, 0)           # 红
QColor(0, 255, 0)           # 绿
QColor(0, 0, 255)           # 蓝
QColor(79, 129, 189)        # 淡蓝
QColor(192, 80, 77)         # 朱红
QColor(155, 187, 89)        # 浅绿
QColor(128, 100, 162)       # 紫
QColor(75, 172, 198)        # 浅蓝
QColor(151, 151, 151)       # 灰
QColor(36, 169, 255)        # 天蓝
QColor(91, 74, 66)          # 深棕
QColor(130, 57, 53)         # 红棕
QColor(137, 190, 178)       # 蓝绿
QColor(201, 186, 131)       # 泥黄
QColor(222, 221, 140)       # 暗黄
QColor(222, 156, 83)        # 橙
QColor(199, 237, 233)       # 亮蓝
QColor(175, 215, 237)       # 蓝灰
QColor(92, 167, 186)        # 蓝绿
QColor(147, 224, 255)       # 浅蓝

5.7 调色板类(QPalette)

​ PySide6 中各种控件和窗口的颜色都由调色板类 QPalette 来定义,可以为窗体和窗体上的控件设置前景色、背景色,可以用 palette() 方法和 setPalette(QPalette) 方法获取和设置窗体及控件的调色板,另外可以通过 QApplication 类的 setPalette(palette) 方法为整个应用程序设置默认的调色板。

QPalette 类有两个基本的概念,一个是 颜色组 ColorGroup,另一个是 颜色角色 ColorRole。

颜色组 ColorGroup 分为 3 种情况:激活状态(Active,获得焦点)、非激活状态(Inactive,失去焦点)和 失效状态(Disabled,不可用),例如进行多窗口操作时,单击其中的一个窗口,可以在窗口中输入数据,则这个窗口是激活状态,其他窗口是非活跃状态。当将一个控件的 enable 属性设置为 False 时(可通过 setEnabled(enable) 方法设置),这个控件就处于失效状态,失效状态的控件不能接受任意输入,例如按钮不能单击、输入框中不能输入文字。对于一个控件,例如一个 Label 标签或 PushButton 按钮,可以设置其文字的颜色,也可以设置其背景颜色。

颜色角色 ColorRole 的作用是对控件或窗体的不同部分分别设置颜色。将 ColorGroup 和 ColorRole 结合起来,可以为控件不同部分不同状态设置不同的颜色。一个窗口由多个控件构成,可以用颜色角色为窗口和窗口中的控件定义不同的颜色。

PySide6 中 颜色组 由枚举常量 QPalette.ColorGroup 确定,QPalette.ColorGroup 可以取 QPalette.Active(或QPalette.Normal)、QPalette.InactiveQPalette.Disabled

颜色角色 由枚举常量 QPalette.ColorRole 确定,QPalette.ColorRole 的枚举值如下所示。

QPalette.WindowText             # 窗口的前景色
QPalette.Window                 # 窗口控件的背景色
QPalette.ButtonText             # 按钮的前景色
QPalette.Button                 # 按钮的背景色
QPalette.Text                   # 文本输入控件的前景色
QPalette.Base                   # 文本输入控件的背景色
QPalette.Placeholder            # 输入框的占位文本的颜色
QPalette.ToolTipText            # 提示信息的前景色
QPalette.ToolTipBase            # 提示信息的背景色
QPalette.BrightText             # 文本的对比色
QPalette.AlternateBase          # 多行输入输出控件行交替背景色
QPalette.HighlightedText        # 所选物体的前景色
QPalette.Highlight              # 所选物体的背景色
QPalette.Link                   # 超链接的颜色
QPalette.LinkVisited            # 已访问的超链接的颜色
QPalette.Mid                    # 与控件的3D效果和阴影效果有关的颜色
QPalette.Midlight               # 与控件的3D效果和阴影效果有关的颜色
QPalette.Light                  # 与控件的3D效果和阴影效果有关的颜色
QPalette.Dark                   # 与控件的3D效果和阴影效果有关的颜色
QPalette.Shadow                 # 与控件的3D效果和阴影效果有关的颜色

​ 可以用 QColor、Qt.GlobalColor、QBrush 或 QGradient 来定义有初始颜色的调色板,其中 QColorQt.GlobalColor 定义的颜色是 纯颜色,而 QBrushQGradient 定义的颜色是可以 渐变 的。

QPalette()
QPalette(button:Union[QColor, Qt.GlobalColor, str])
QPalette(button:Union[QColor, Qt.GlobalColor, str, int], window:Union[QColor, Qt.GlobalColor, str])
QPalette(palette:Union[QPalette, Qt.GlobalColor, QColor])
QPalette(windowText:Union[QBrush, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap], button, light, dark, mid, text, bright_text, base, window)
QPalette(windowText:Union[QColor, Qt.GlobalColor, str], window, light, dark, mid, text, base)

窗口上的各种控件及窗口都会有调色板属性,通过控件或窗口的 palette() 方法可以获取调色板,然后对获取的调色板进行颜色设置,设置完成后通过控件或窗口的 setPalette(palette) 方法将设置好的调色板重新赋给控件或窗口。当然也可以定义一个全新的调色板对象,通过控件或窗口的 setPalette(palette) 方法将这个全新的调色板赋予控件或窗口。

对控件或窗口的不同部分不同状态设置颜色需要用调色板的 setColor() 方法或 setBrush() 方法。用 brush() 方法可以获得不同状态、不同角色的画刷,通过画刷的 color() 方法可以获得颜色 QColor 对象。

如果需要设置控件的背景色,应将背景色设置成自动填充模式,通过控件的方法 setAutoFillBackground(True) 来设置。对于按钮通常还需要关闭 3D 效果,通过按钮的 setFlat(True) 来设定。

color(cr:QPalette.ColorRole) -> QColor
color(cg:QPalette.ColorGroup, cr:QPalette.ColorRole) -> QColor
setColor(cr:QPalette.ColorRole, color:Union[QColor, Qt.GlobalColor, str]) -> None
setColor(cg:QPalette.ColorGroup, cr:QPalette.ColorRole, color:Union[QColor, Qt.GlobalColor, str]) -> None

brush(cr:QPalette.ColorRole)
brush(cg:QPalette.ColorGroup, cr:QPalette.ColorRole)
setBrush(cr:QPalette.ColorRole, brush:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap]) -> None
setBrush(cg:QPalette.ColorGroup, cr:QPalette.ColorRole, brush:Union[QBrush, Qt.BrushStyle, Qt.GlobalColor, QColor, QGradient, QImage, QPixmap]) -> None

currentColorGroup() -> QPalette.ColorGroup
setCurrentColorGroup(cg:QPalette.ColorGroup) -> None

windowText() -> QBrush
window() -> QBrush

buttonText() -> QBrush
button() -> QBrush

text() -> QBrush
base() -> QBrush
placeholderText() -> QBrush
toolTipText() -> QBrush
toolTipBase() -> QBrush
brightText() -> QBrush
alternateBase() -> QBrush

highlightedText() -> QBrush
highlight() -> QBrush

link() -> QBrush
linkVisited() -> QBrush

mid() -> QBrush
midlight() -> QBrush
light() -> QBrush
dark() -> QBrush
shadow() -> QBrush

isBrushSet(cg:QPalette.ColorGroup, cr:QPalette.ColorRole) -> bool
isEqual(cr1:QPalette.ColorRole, cr2:QPalette.ColorRole) -> bool
import sys
from random import seed, randint

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QPalette, QFont, QColor

class SetPalette(QWidget):
    def __init__(self):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__()
        # 2.设置窗口尺寸
        self.setGeometry(200, 200, 1200, 500)
        # 3.设置窗口标题
        self.setWindowTitle("设置调色板示例")

        self.create_labels()
        self.set_label_color()
        self.get_label_color_rgb()

    def create_labels(self):
        self.labels = list()
        font = QFont("黑体", pointSize=20)
        string = "Nice to Meet You! 很高兴认识你!"
        for i in range(10):
            # 在窗口上创建标签控件
            label = QLabel(self)
            # 标签的位置和尺寸
            label.setGeometry(5, 50 * i, 1200, 40)
            # 设置标签文字
            label.setText(f"{str(i)} : {string}")
            # 设置标签文字的字体
            label.setFont(font)
            self.labels.append(label)

    def set_label_color(self):
        seed(12)
        for label in self.labels:
            # 定义颜色
            color_base = QColor(randint(0, 255), randint(0, 255), randint(0,255))
            color_text = QColor(randint(0, 255), randint(0, 255), randint(0,255))

            palette = label.palette()
            # 定义前景色
            palette.setColor(palette.ColorGroup.Active, palette.ColorRole.WindowText, color_text)
            # 定义背景色
            palette.setColor(palette.ColorGroup.Active, palette.ColorRole.Window, color_base)

            # 设置背景自动填充
            label.setAutoFillBackground(True)

            # 设置调色板
            label.setPalette(palette)

    def get_label_color_rgb(self):
        for label in self.labels:
            # 获取文字颜色的RGB值
            r_text, g_text, b_text, a_text = label.palette().windowText().color().getRgb()
            # 获取背景颜色的RGB值
            r, g, b, a = label.palette().window().color().getRgb()
            text = f"{label.text()}背景颜色:{r} {g} {b} 文字颜色 {r_text} {g_text} {b_text}"
            label.setText(text)

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = SetPalette()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

image-20240614093038975

5.8 图像类(QImageQPixmapQPictureQBitmap)

PySide6 的图像类有 QImageQPixmapQPictureQBitmap 四大类,这几个类都是从 QPaintDevice 类继承而来的,它们的继承关系如下所示。

图像类的继承关系

​ QPixmap 适合将图像显示在电脑屏幕上,可以使用 QPixmap 在程序之中打开 png、jpeg 等图像文件。

QBitmap 是 QPixmap 的一个子类,它的色深限定为 1,颜色只有黑白两种,用于制作光标 QCursor 或画刷 QBrush 等。

QImage 专门读取像素文件,其存储独立于硬件,是一种 QPaintDevice 设备,可以直接在 QImage 上用 QPainter 绘制图像,可以在另一个线程中对其进行绘制,而不需要在 GUI 线程中处理,使用这一方式可以很大幅度提高 GUI 响应速度。

当图片较小时,可直接用 QPixmap 进行加载,当图片较大时用 QPixmap 加载会占很大的内存,这时用 QImage 进行加载会快一些, QImage 可以转成 QPixmap。

QPicture 是一个可以记录和重现 QPainter 命令的绘图设备,它还可以保存 QPainter 绘制的图形,QPicture 将 QPainter 的命令序列化到一个 IO 设备上,保存为一个平台独立的文件格式。QPicture 与平台无关,可以用到多种设备之上,比如 svg、pdf、ps、打印机或者屏幕。

QImage、QPixmap、QBitmap、QPicture 这 4 个类都有 load() 和 save() 方法,用于从文件中加载图片和保存图片;QImage 和 QPixmap 类有 fill() 方法,可以填充某种颜色的图形;QPixmap 类的 toImage() 方法可以将 QPixmage 图像转换成 QImage 图像。

QPaintDevice 类常用方法如下:

width() -> int          # 获取图像的宽度
height() -> int         # 获取图像的高度
depth() -> int          # 获取图像的深度
devType() ->int         # 返回设备号

5.8.1 QPixmap类

用 QPixmap 类创建实例的方法如下,其中 w、h 和 QSize 指定图像的像素数(尺寸大小),str 是一个图像文件。

QPixmap()
QPixmap(w:int, h:int)
QPixmap(size:QSize)
QPinxmap(fileName:str, format:str=None, flags:ImageConversionFlags=Qt.AutoColor)
QPixmap(image:QImage)

QPixmap 类的常用方法下所示:

# 示例方法
copy(rect:QRect=QRect()) -> QPixmap                                                                                                 # 深度复制图像的局部区域
copy(x:int, y:int, width:int, height:int) -> QPixmap                                                                                # 深度复制图像的局部区域
load(fileName:str, format:str=None, flags:Qt.ImageConversionFlags=Qt.AutoColor) -> bool                                             # 从文件加载图像,成功返回True
save(device:QIODevice, format:str=None, quality:int=-1) -> bool                                                                     # 保存图像到设备,成功返回True
save(fileName:str, forma:str=None, quality=-1) -> bool                                                                              # 保存图像到文件,成功返回True
scaled(s:QSize, aspectMode:Qt.AspectMode=Qt.IgnoreAspectRatio, mode:Qt.TransformationMode=Qt.FastTransformation) -> QPixmap         # 缩放图像
scaled(w:int, h:int, aspectMode:Qt.AspectMode=Qt.IgnoreAspectRatio, mode:Qt.TransformationMode=Qt.FastTransformation) -> QPixmap    # 缩放图像
scaledToHeight(h:int, mod:Qt.TransformationMode=Qt.FastTransformation) -> QPixmap                                                   # 缩放图像到指定高度
scaledToWidth(w:int, mode:Qt.TransformationMode=Qt.FastTransformation) -> QPixmap                                                   # 缩放图像到指定宽度
mask() -> QBitmap                                                                                                                   # 获取遮掩图
setMask(arg__1:Union[QBitmap, str]) -> None                                                                                         # 设置遮掩图
swap(other:Uninor[QPixmap, QBitmap]) -> None                                                                                        # 与别的图像进行交换
toImage() -> QImage                                                                                                                 # 转换为QImage对象
convertFromImage(img:QImage, flags:Qt.ImageConversionFlags=Qt.AutoColor) -> bool                                                    # 从QImage对象转换为QPixmap对象,成功返回True
transformed(arg__1:QTransform, mode:Qt.TransformationMode=Qt.FastTransformation) -> QPixmap                                         # 将图像进行旋转、缩放、平移和错切等交换
rect() -> QRect                                                                                                                     # 获取图像的矩形区域
size() -> QSize                                                                                                                     # 获取图像的大小
fill(fillColor:Union[QColor, Qt.GlobalColor]=Qt.white) -> None                                                                      # 用指定颜色填充图像
hasAlpha() -> bool                                                                                                                  # 判断图像是否有透明度
isQBitmap() -> bool                                                                                                                 # 判断是否为QBitmap对象


# 静态方法
fromImage(image:QImage, flags:Qt.ImageConversionFlags=Qt.AutoColor) -> QPixmap                                                      # 从QImage对象创建QPixmap对象 

​ 其中用 save(str, format=None, quality=-1) 方法可以保存图像,成功则返回 True。其中 str 是保存的文件路径和文件名;format 是文件类型,用字节串表示,如果是 None,则根据文件的扩展名确定类型;quality 的取值为 0 ~ 100 的整数,取 -1 表示采用默认值,对于有损压缩的文件格式来说,它表示图像保存的质量,质量越低压缩率越大。

​ 用 load(str, format=None, flags=Qt.AutoColor) 方法可以从文件中加载图像,其中 flags 是 Qt.ImageConversionFlag 的枚举类型,表示颜色的转换模式,可以取 Qt.AutoColor(由系统自动决定)、Qt.ColorOnly(彩色模式)或 Qt.MonoOnly(单色模式)。用 setMask(QBitmap) 方法设置遮掩图,黑色区域显示,白色区域不显示。

QPixmap 可以读写的文件格式:

图像格式 是否可以读写
BMP Read/Write
GIF Read
JGP Read/Write
JPEG Read/Write
PNG Read/Write
PBM Read
PGM Read
PPM Read/Write
XBM Read/Write
XPM Read/Write
import sys

from PySide6.QtWidgets import QApplication, QWidget,QVBoxLayout
from PySide6.QtWidgets import QLabel
from PySide6.QtCore import Qt
from PySide6.QtGui import QPixmap

class MyPixmap(QWidget):
    def __init__(self):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__()
        # 2.设置窗口尺寸
        self.setGeometry(200, 200, 800, 500)
        self.setup_ui()

    def setup_ui(self):
        # layout =QVBoxLayout()
        # 1.创建标签控件
        self.label = QLabel("标签文字", self)
        # # 2.设置标签文字中心对齐
        self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        # # 3.获取字体
        font = self.label.font()
        # # 4.设置字体大小
        font.setPointSize(10)
        # # 5.给标签控件设置字体
        self.label.setFont(font)
        # # 6.给标签控件添加图像,需要注意路径
        pixmap = QPixmap(r".\GUI类\1.png")
        self.label.setPixmap(pixmap)


if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication([])
    # 2.创建一个窗口
    window = MyPixmap()
   
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

image-20240614104915850

5.8.2 QImage类

QImage绘图设备,可以直接用 QPainter 在 QImage 上绘制图像,QImage 可以直接操作图像上的像素。用 QImage 类创建实例的方法如下:

QImage()
QImage(filename:str, format:Union[bytes, NoneType]=None)
QImage(size:QSize, format:QImage.Format)
QImage(width:int, height:int, format:QImage.Format)
QImage(data:bytes, width:int, height:int, bytesPerLine:int, format:QImage.Format)
QImage(data:bytes, width:int, height:int, format:QImage.Foramt)

其中,format 是 QImage.Format 的枚举值,指定 QImage 的图形文件的格式。

QImage 可以对图像的像素颜色进行深入操作,可以对图像的颜色 RGB 值进行翻转,可以获取每个像素点的 RGB 值,并可以设置每个像素点的 RGB 值,因此在获取一个像素点的 RGB 值后,应对其进行处理。例如将 R、G、B 三个值取原 R、G、B 值的平均值,可以使图像灰度化;R、G、B 值都增加或减少一个相同的值,可以使图像亮度增加或降低,但是注意不要超过 255 和低于 0;用卷积计算可以进行锐化、模糊化、调节色调等处理。

format() -> QImage.Format                                                                                                               # 获取图像格式
convertTo(f:str, flags:Qt.ImageConversionFlag=Qt.AutoColor) -> None                                                                     # 将图像转换为指定格式
copy(rect:QRect=QRect()) -> QImage                                                                                                      # 从指定位置复制图像
copy(x:int, y:int, w:int, h:int) -> QImage                                                                                              # 从指定位置复制图像
fill(color:Union[QColor, Qt.GlobalColor, str]) -> None                                                                                  # 用指定颜色填充图像
load(fileName:str, format:str=None) -> bool                                                                                             # 从文件加载图像,成功返回True                               
save(device:QIODevice, format:str, quality:int=-1) -> bool                                                                              # 将图像保存到指定设备,成功返回True
save(fileName:str, format:str=None, quality:int=-1) -> bool                                                                             # 将图像保存到指定文件,成功返回True
scaled(s:QSize, aspectMode:Qt.AspectRatioMode=Qt.IgnoreAspectRatio, mode:Qt.TransformationMode=Qt.FastTransformation) -> QImage         # 将图像的长度和宽度缩放到新的宽度和高度,返回新的QImage对象
scaled(w:int, h:int, aspectMode:Qt.AspectRatioMode=Qt.IgnoreAspectRatio, mode:Qt.TransformationMode=Qt.FastTransformation) -> QImage    # 将图像的长度和宽度缩放到新的宽度和高度,返回新的QImage对象
scaledToHeight(h:int, mode:Qt.TransformationMode=Qt.FastTransformation) -> QImage                                                       # 将图像的高度缩放到指定高度,返回新的QImage对象 
scaledToWidth(w:int, mode:Qt.TransformationMode=Qt.FastTransformation) -> QImage                                                        # 将图像的宽度缩放到指定宽度,返回新的QImage对象
size() -> QSize                                                                                                                         # 获取图像的尺寸
setPixelColor(pt:QPoint, c:QColor) -> None                                                                                              # 设置指定位置的像素颜色
setPixelColor(x:int, y:int, c:QColor) -> None                                                                                           # 设置指定位置的像素颜色
pixelColor(pt:QPoint) -> QColor                                                                                                         # 获取指定位置的像素颜色
pixelColor(x:int, y:int) -> QColor                                                                                                      # 获取指定位置的像素颜色
setText(key:str, value:str) -> None                                                                                                     # 嵌入字符串
text(key="") -> str                                                                                                                     # 获取嵌入的字符串
textKeys() -> list[str]                                                                                                                 # 获取嵌入的字符串的键
rgbSwap() -> None                                                                                                                       # 颜色翻转,交换红色和绿色通道
rgbSwapped() -> QImage                                                                                                                  # 返回颜色翻转后的图形,交换红色和绿色通道
invertPixels(mode:QImage.InvertMode=QImage.InvertMode.InvertRgb) -> None                                                                # 反转图像的像素颜色
transformed(matrix:QTransform, mode:Qt.TransformationMode=Qt.FastTransformation) -> QImage                                              # 应用变换矩阵,返回新的QImage对象
mirror(horizontally:bool=False, vertically:bool=True=false) -> None                                                                     # 对图形进行镜像操作
mirrored(horizontally:bool=False, vertically:bool=false) -> QImage                                                                      # 镜像图像,返回新的QImage对象
setColorTable(colors:Sequence[int]) -> None                                                                                             # 设置颜色表
colorTable() -> list[int]                                                                                                               # 获取颜色表
color(i:int) -> int                                                                                                                     # 根据索引值获取获取颜色表中的颜色
setPixel(pt:QPoint, index_or_rgb:int) -> None                                                                                           # 设置指定位置的像素颜色或索引
setPixel(x:int, y:int, index_or_rgb:int) -> None                                                                                        # 设置指定位置的像素颜色或索引
pixel(pt:QPoint) -> int                                                                                                                 # 获取指定位置的像素颜色或索引
pixel(x:int, y:int) -> int                                                                                                              # 获取指定位置的像素颜色或索引
pixelIndex(pt:QPoint) -> int                                                                                                            # 获取指定位置的像素颜色索引值
pixelIndex(x:int, y:int) -> int                                                                                                         # 获取指定位置的像素颜色索引值

5.8.3 QBitmap类

QBitmap 是只能存储 黑白图像位图,可以用于图标(QCursor)或画刷(QBrush),QBitmap 可以从图像文件或 QPixmap 中转换过来,也可以用 QPainter 来绘制。用 QBitmap 类创建位图实例对象的方法如下,fileName 是图像文件路径。

QBitmap()
QBitmap(Union[QPixmap, QImage])
QBitmap(w:int, h:int)
QBitmap(size:QSize)
QBitmap(filename:str, format:str=None)

QBitmap 类继承自 QPixmap,因此具有 QPixmap 的方法。另外 QBitmap 的 clear() 方法可以清空图像内容;transformed(QTransform) 方法可以对位图进行转换,返回转换后的位图,fromImage(QImage,flags=Qt.AutoColor) 方法可以从 QImage 中创建位图并返回位图,其中参数 flags 是 Qt.ImageConversionFlag 的枚举值,表示转换模式,可以取 Qt.AutoColor(由系统自动决定)或 Qt.MonoOnly(单色模式)。

5.8.4 QPicture类

QPicture 是一个读写设备,用 QPainter 可以直接在 QPicture 上绘图,并可以记录和重放 QPainter 的绘图过程。QPicture 采用专用的二进制存储格式,独立于硬件,可以在任何设备上显示。用 QPicture 类创建图像实例的方法如下所示,其中 formatVersion 用于设置匹配更早版本的 Qt,-1 表示当前版本。

QPicture(formatVersion:int=-1)

QPicture 类的常用方法如下:

play(p:QPainter) -> bool                    # 重新执行QPainter的绘制命令,成功则返回True
load(dev:QIODevice) -> bool                 # 从设备中加载图像
load(fileName:str) -> bool                  # 从文件中加载图像
save(dev:QIODevice) -> bool                 # 保存图像到设备中
save(fileName:str) -> bool                  # 保存图像到文件中
setBoundingRect(r:QRect) -> None            # 设置绘图区域
boundingRect() -> QRect                     # 获取绘图区域
setData(data:str) -> None                   # 设置图像上的数据
data() -> object                            # 返回执行数据的指针
size() -> int                               # 返回数据的数量

5.9 图标类(QIcon)

​ 图标类是 QIcon,用 QIcon 类创建图标实例的方法如下。可以从 QPixmap 中创建,也可以从一个图片文件中直接创建,另外还可以利用资源文件中的图片创建图标。当从 QPixmap 创建图标时,系统会自动产生窗口不同状态下对应的图像,比如窗口在禁用状态下其图标为灰色;从文件构造图标时,文件并不是立刻加载,而是当图标要显示时才加载。

QIcon()
QIcon(pixmap:QPixmap)
QIcon(filename:str)

QIcon 类的主要方法是 addFile()和 addPixmap(),它们的格式为 addFile(fileName,size=QSize(),mode=Normal,state=Off)addPixmap(QPixmap,mode=Normal,state=Off),其中,mode 可以取 QIcon.Normal(未激活)、QIcon.Active(激活)、QIcon.Disabled(禁用)和 QIcon.Seleted(选中),state 可以取 QIcon.OnQIcon.off。另外,QIcon 的 pixmap() 方法可以获取图标的图像, isNull() 方法可以判断图标的图像是否是无像素图像。

import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton
from PySide6.QtGui import QPixmap, QIcon

class MyWidget(QWidget):
    def __init__(self):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__()
        # 2.创建图像控件
        pixmap = QPixmap()
        # 3.加载图片
        pixmap.load("./1.jpg")
        # 4.创建图标控件
        icon = QIcon(pixmap)
        # 5.设置窗口图标
        self.setWindowIcon(icon)
        # 6.创建按钮控件
        button = QPushButton(self)
        # 7.设置按钮图标
        button.setIcon(icon)

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = MyWidget()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

image-20240614133917412

5.10 光标类(QCursor)

​ 将光标移动到不同的控件上,并且控件在不同的状态下,可以为控件设置不同的光标形状。定义光标需要用到 QtGui 模块中的 QCursor 类。定义光标形状有两种方法,一种是用标准的形状 Qt.CursorShape,另一种是用自己定义的图片来定义。如果用自定义的图片来定义光标形状,需要设置光标的热点 hotX 和 hotY,hotX 和 hotY的值是整数,如果取负值,则以图片中心点为热点,即hotX=bitmap().width()/2,hotY=bitmap().height()/2

用 QCursor 创建光标实例的方式如下:

QCursor()
QCursor(shape:Qt.CursorShape)
QCursor(pixmap:Union[QPixmap, QIamge, str], hotX:int=-1, hotY:int=-1)
QCursor(bitmap:Union[QBitmap, str], mask:Uninon[QBitmap, str], hotX:int=-1, hotY:int=-1)

其中 Qt.CursorShape 设置 标准的光标形状mask 参数是 遮掩图像,可以用 QPixmap 的 setMask(QPixmap) 方法提前给光标设置遮掩图。

​ 如果光标图像和遮掩图的颜色值都是 1,则结果是黑色;如果光标图像和遮掩图的颜色值都是 0,则结果是透明色;如果光标图像的颜色值是 0,而遮掩图的颜色值 1,则结果是白色。反之在 Windows 上是 XOR 运算的结果,其他系统上未定义。

标准的光标形状如下:

标准的光标形状

光标类的常用方法如下:

# 实例方法
setShape(newShape:Qt.CursontShape) -> None              # 设置光标形状
shape() -> Qt.CursontShape                              # 获取光标形状
bitmap() -> QBitmap                                     # 获取QBitmap图
pixmap() -> QPixmap                                     # 获取QPixmap图
hotSpot() -> QPoint                                     # 获取光标热点
mask() -> QBitmap                                       # 获取遮掩图

# 静态方法
setPos(screen: QScreen, p: QPoint) -> None              # 设置光标热点到屏幕坐标系下的指定位置
setPos(screen: QScreen, x: int, y: int) -> None         # 设置光标热点到屏幕坐标系下的指定位置
pos() -> QPoint                                         # 获取光标热点在屏幕坐标系下的位置
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QCursor
from PySide6.QtGui import QPixmap, QBitmap, QPainter
from PySide6.QtCore import Qt, QRect

class SetCursor(QWidget):
    def __init__(self):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__()
        # 2.创建位图
        bitmap = QBitmap(32, 32)
        bitmap_mask = QBitmap(32, 32)

        # 3.填充颜色
        bitmap.fill(Qt.GlobalColor.black)
        bitmap_mask.fill(Qt.GlobalColor.white)

        # 4.设置光标
        self.setCursor(QCursor(bitmap, bitmap_mask))

    def paintEvent(self, event):
        pixmap = QPixmap()
        rect = QRect(0, 0, self.width(), self.height())
        pixmap.load("1.jpg")

        painter = QPainter(self)
        painter.drawPixmap(rect, pixmap)

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = SetCursor()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

image-20240614134256745

参考链接:https://www.cnblogs.com/kurome/p/17787987.html

posted @ 2025-04-16 08:53  Yasuo_Hasaki  阅读(62)  评论(0)    收藏  举报
//雪花飘落效果