PyQt5基础知识大全

本文介绍了如何在PyQt项目中结合OpenCV进行图像处理,包括设置窗口背景透明、使用QSS和QPalette,以及高级控件如QPainterPath和QSplitter的应用。此外,还涵盖了事件处理、多线程、信号槽连接和UI优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PyQt5 Reference Guide
Qt 5.15 All Classes
如何利用 PyQT5 搭建 YOLOv5 可视化界面?
基于PyQt5的图像分类标注工具
基于深度学习的中文车牌识别与管理系统(含UI界面,Python代码)
PYQT5+Pytorch的猫狗分类(从数据集制作->网络模型搭建和训练->界面演示)
AI应用软件开发实战专栏【链接】
Python 小白从零开始 PyQt5 项目实战(8)汇总篇(完整例程)
PyQt:桌面程序设计的饕餮盛宴
快速掌握PyQt5
PyQt5新手教程(六万字)

QSS(Qt StyleSheet,Qt样式表)

  • 语法结构
    每条QSS样式由两部分组成:1. 选择器,该部分指定要美化的控件;2. 声明,该部分指定要在控件上使用的属性和值
  • ‌常用属性‌:color(前景色)、background-color(背景色)、border-radius(圆角)font(字体)、padding(内边距)、margin( 外边距)、border(边框样式)、text-align 控件文本对齐方式、text-indent 控件文本缩进
  • 子控件:(QComboBox ::drop-down 下拉按钮 ::item 下拉项;QScrollBar ::handle 滑块 ::add-line 增加按钮 ::sub-line 减少按钮;QSpinBox ::up-button 上箭头 ::down-button 下箭头;QGroupBox ::title 标题 ::indicator 指示器;QTabWidget ::tab-bar 标签栏 ::tab 单个标签;QMenu ::item 菜单项 ::separator 分隔符)
  • 伪状态:伪状态是指组件一种状态,诸如选中、关闭、活跃、或者是鼠标放上去、鼠标点击等。(:hover 鼠标悬停,:pressed 鼠标按下,:checked 已选中状态,:focus 获得焦点,:open 展开状态(如 QComboBox),:closed 折叠状态)
  • Qss 支持不同的尺寸和单位来定义样式,包括像素(px)、绝对长度(cm、mm、in、pt、pc)、相对长度(em、ex、rem)、百分比(%)等,
QPushButton {color: red} #QPushButton是设置的选择器,而大括号里的color: red分别为属性和值。这条样式会将所有的QPushButoon实例和它子类的文本颜色都设置为红色。
QPushButton {color: red; background-color: blue} #可以声明多个属性和值,各对属性和值之间用分号分隔
QPushButton, QLabel, QLineEdit {color: red} #同时指定多个选择器
QWidget {
    margin: 5px;          /* 外边距 */
    padding: 10px;        /* 内边距 */
    border: 2px solid #555; /* 边框 */
    border-radius: 8px;   /* 圆角半径 */
    border-top-right-radius: 0; /* 单独设置 */
}

在这里插入图片描述
在这里插入图片描述

  • 第三方工具
    1、QDarkStyleSheet是一种基于QSS的Qt主题,用于实现暗色主题。使用QDarkStyleSheet可以使界面更加美观、护眼,特别适用于长时间使用的应用程序。
    2、QSS-Borderless-Window是一种用于实现无边框窗口的库。使用QSS-Borderless-Window可以使界面更加简洁、美观。
    PyQt之QSS美化
    QT 样式表 (QSS) 指南

打包发布

Python图形界面开发的几种方案

主要有3种选择:

  • Tkinter
    基于Tk的Python库,这是Python官方采用的标准库,优点是作为Python标准库、稳定、发布程序较小,缺点是控件相对较少、图形化界面不够美观。
  • wxPython
    基于wxWidgets的Python库,优点是控件比较丰富,缺点是稳定性相对差点、文档少、用户少。
  • PySide2/PySide6、PyQt5/PyQt6
    基于Qt 的Python库,优点是控件比较丰富、跨平台体验好、文档完善、用户多。缺点是库比较大,发布出来的程序比较大。两者 API 设计几乎一致,代码迁移成本较低。
    PyQt:使用 GPL(GNU 通用公共许可证) 或商业许可。若闭源分发,需购买商业许可证。
    PySide:使用 LGPL(宽松的 GNU 通用公共许可证)。允许闭源商业使用(无需付费),只需动态链接库(无需开放源代码)。

高级容器控件

  • 选项卡控件(QTabWidget)页面切换逻辑由控件自身管理,无需额外代码。适用场景:内容分类明确:例如浏览器的多标签页、设置界面的不同分类。快速切换需求:用户需要频繁在多个页面间跳转。页面数量较少:标签栏宽度有限,过多标签会导致体验下降。
  • 堆叠窗口控件(QStackWidget)需要开发者手动管理页面切换逻辑(例如通过索引或名称切换)。适用场景:步骤流程:如安装向导、表单分步填写。动态内容切换:根据用户权限或操作动态显示不同页面。
  • 停靠控件(QDockWidget)
  • 容纳多文档的窗口(QMdiArea&QMdiSubWindow)
    PyQt5学习笔记(十一)高级容器控件

关于布局管理器

1、设置控件上下左右间距
2、layoutStrtch属性设置内部控件大小比例,布局内部有几个控件,会有几个数值,用英文逗号隔开。
3、设置固定大小
4、弹簧的使用,按钮的大小不足以充满布局时,布局会自动拉大控件之间的距离。可以使用弹框,弹簧存在时,不会拉大控件之间距离
5、分裂器布局,可以在程序运行中,在UI上拖动分裂来调整2个控件的所占大小的比例
6、 管理布局的函数中有一个addStretch(int) 方法,该方法就是添加一个占位符,而占位符的大小就是其中填入的数字。我们可以看到在示例中先添加了一个大小为1的占位符,然后再添加用于显示图片的QLabel,最后再加了一个大小为1的占位符。这样做的目的就是为了让这个QLabel控件居中。若将添加的第一个占位符(即左边的占位符)大小设为2,那么QLabel就会偏右,因为左边的占位符大小比QLabel右边的占位符大。
Qt控件布局使用介绍

QSizePolicy

控件的sizeHint的值是固定的。sizepolicy只有与布局结合使用才有意义。决定了当控件的父布局或窗口大小发生变化时,控件应该如何调整自身的大小。
Fixed: 无法调整大小
Minimum: 不能小于sizeHint
Maximum: 不能大于sizeHint
Preferred: 优先使用sizeHint
Expanding: 倾向于占用更多空间
MinimumExpanding: 不能小于sizeHint,但倾向于占用更多空间
Ignored: 完全忽略sizeHint
课时19.尺寸策略(sizePolicy)
Qt::SizePolicy、MinimumSize、MaximumSize与控件大小的关系

事件处理函数

一个界面组件产生的事件会发送给其event()函数处理,如果event()函数不做任何处理,就自动调用事件处理的默认处理函数。继承至QWidget的控件都有事件处理函数。PyQt为事件处理提供了两种机制:高级的信号与槽机制、低级的事件处理程序。事件处理机制本身很复杂,是PyQt底层的知识点,当采用信号与槽机制处理不了时,才会考虑使用事件处理机制。这里的事件常见如下类型:键盘事件、鼠标事件、拖放事件、滚轮事件、定时事件、焦点事件、进入和离开事件(光标移入控件或者移出),移动事件(窗口位置变化),显示和隐藏事件,窗口事件(窗口是否为当前窗口)

actionEventchangeEventchildEventcloseEventcontextMenuEventcustomEvent
dragEnterEventdragLeaveEventdragMoveEventdropEvententerEventfocusInEvent
focusOutEventhideEventinputMethodEventinstallEventFilterkeyPressEventkeyReleaseEvent
leaveEventmouseDoubleClickEventmouseMoveEventmousePressEventmouseReleaseEventmoveEvent
nativeEventpaintEventremoveEventFilterresizeEventshowEventtabletEvent
timerEventwheelEvent

事件过滤器函数(eventFilter)

用于在事件到达目标部件之前截获并处理事件,当一个事件发生时,例如鼠标点击或键盘按键按下,事件首先会被发送到应用程序的事件队列。在事件被分发给目标部件进行处理之前,会先检查是否有事件过滤器对该事件感兴趣。如果有,事件过滤器会先接收到事件,并且可以选择处理事件、修改事件或者将事件传递给目标部件进行正常处理。
1、通过调用installEventFilter方法来安装事件过滤器。
2、eventFilter(self,watched,event)其中, watched参数表示被观察的部件(即安装了事件过滤器的目标部件),event参数是发生的事件对象
3、返回值为True则该事件不会再传递,否则会继续传递。
PyQt中eventFilter事件过滤器讲解及其目前版本中的弊端规避

QMetaObject 和 Q_ARG

是 PyQt/Qt 框架中用于实现跨线程通信和元对象系统操作的核心类。
1、QMetaObject - 元对象系统核心
作用:提供对 Qt 对象元信息的访问;实现信号槽机制和动态属性系统的基础;支持跨线程安全的方法调用
2. Q_ARG - 类型安全的参数包装
作用:封装方法调用的参数;在跨线程调用时保持类型安全;支持 Qt 元对象系统识别的所有数据类型

    def add_qt_sink(self, text_widget):
        """ 添加PyQt日志展示组件 """

        def qt_sink(message):
            # 确保在主线程更新UI
            from PyQt5.QtCore import QMetaObject, Q_ARG
            QMetaObject.invokeMethod(text_widget,
                                     "append",
                                     Qt.QueuedConnection,
                                     Q_ARG(str, message.record["message"]))

        logger.add(qt_sink, format="{message}", level="INFO")

信号与槽

详解PyQt5信号与槽的几种高级玩法
PyQt5的信号与槽函数
在GUI编程中,当改变一个控件的状态时,通常需要通知另一个控件,也就是实现了对象之间的通信。在早期的GUI编程中使用的是回调机制,回调实际上是利用函数指针来实现,当我们希望某件事发生时处理函数能够获得通知,就需要将回调函数的指针传递给处理函数,这样处理函数就会在合适的时候调用回调函数。 回调有两个明显的缺点:它们不是类型安全的,我们无法保证处理函数传递给回调函数的参数都是正确的。回调函数和处理函数紧密耦合,源于处理函数必须知道哪一个函数被回调。
在Qt中则使用一种新机制信号与槽。

  • 信号与槽的三种连接方法
    1、@pyqtSlot()
    格式:on_(控件对象名)_信号名(self,内置参数)
    结合QtCore.QMetaObject.connectSlotsByName(Form) 自动将信号连接到槽函数
    2、connect()
    格式: (控件名称).(信号名称).connect(槽函数名称)
    有参数时,槽函数名称部分写成lambda 参数名:函数名(参数名)
    没有参数时槽函数不用写双括号()
    3、参数(信号名字) = 函数
    def doClicked(self):
    print(self.sender(), ‘clicked’)
    pushButton = QPushButton(‘按钮’, self, clicked=self.doClicked)

  • 信号与槽有三种类型:内置信号与槽、装饰器的信号与槽、自定义信号与槽(内置信号和自定义槽函数、自定义信号和内置槽函数)。

  • 信号-槽机制只是指定信号如何连接到槽,信号定义的参数被传递给槽,而额外的参数(用户定义)不能直接传递给槽函数传递自定义参数: lambda 匿名表达式、 functools 的 partial 偏函数。

    def checkbox_init(self):
        self.checkbox1.setChecked(True)  # 1
        # self.checkbox1.setCheckState(Qt.Checked)                                                  # 2
        self.checkbox1.stateChanged.connect(lambda: self.on_state_change_func(self.checkbox1))  # 3

        self.checkbox2.setChecked(False)
        # self.checkbox2.setCheckState(Qt.Unchecked)
        self.checkbox2.stateChanged.connect(lambda: self.on_state_change_func(self.checkbox2))

        self.checkbox3.setTristate(True)  # 4
        self.checkbox3.setCheckState(Qt.PartiallyChecked)  # 5
        self.checkbox3.stateChanged.connect(lambda: self.on_state_change_func(self.checkbox3))

    def on_state_change_func(self, checkbox):  # 6
        print('{} was clicked, and its current state is {}'.format(checkbox.text(), checkbox.checkState()))
  • QT 信号-槽连接类型
    1、Qt::DirectConnection(直连方式)(信号与槽函数关系类似于函数调用。同步运行)
    2、Qt::QueuedConnection(排队方式)(此时信号被塞到信号队列里了,信号与槽函数关系类似于消息通信。异步运行)
    3、Qt::AutoConnection(自己主动方式) Qt的默认连接方式,信号的发出和接收这个信号的对象同属一个线程,那个工作方式与直连方式同样。否则工作方式与排队方式同样。
  • QTimer::singleShot这是个静态函数,能够在给定的时间间隔后调用槽,并不是多次触发该槽函数,该槽函数只执行一次。使用此函数非常方便,也不必创建本地qTimer对象。
  • self.sender()通常在槽函数中被调用,用于获取发出信号的对象。这意味着,如果你在一个槽函数中使用了self.sender(),你就可以知道是哪个对象触发了这个槽函数。
    	btn_prev = QPushButton('<')
        btn_next = QPushButton('>')

        btn_prev.clicked.connect(self.on_btn)
        btn_next.clicked.connect(self.on_btn)
    def on_btn(self):
        key = self.sender().text()
        if key == '<':
            self.curr = (self.curr - 1) % len(self.photos)
        else:
            self.curr = (self.curr + 1) % len(self.photos)

处理密集型耗时事件的两种方法

1、QThread多线程
2、QApplication.processEvents()
在执行耗时操作时,使用 QApplication.processEvents() 可以防止界面卡顿。例如,在长时间循环中调用此函数,可以确保界面仍然响应用户的交互操作,如按钮点击和窗口拖动等。

线程、进程

  • PyQt不允许从其主线程外部访问任何类型的对象,这意味着外部线程无法更新、设置任何控件或部件。在PyQt中使用线程的话最好使用用QThread,QThread基于QObject,QObject的好处是享受PyQt的信号槽机制。在QObject中自定义信号,通过信号发射和接收实现与主线程通讯。该方式需要重写QThread类中的run方法

  • quit()函数是用来停止QThread的,但是由于Qt本身是事件循环机制,所以在调用完quit()后,QThread可能还没有完全停止,此时如果执行delete,程序就会报错。==在执行quit()后,调用wait()==来等待QThread子线程的结束(即从run()函数的返回),这样就能保证在清除QThread时,其子线程是停止运行的。默认情况下,run()通过调用exec()启动事件循环,并在线程内部运行一个Qt事件循环。线程会一直运行事件循环,直到显式调用 quit() 或 exit() 来停止事件循环。quit() 是非阻塞的,它只是发出一个退出事件请求,让事件循环能够自然地退出。尽管 quit() 发出请求让事件循环退出,但它并不等待线程实际结束。此时,线程可能还在处理已经在事件队列中的任务。wait() 会阻塞当前线程,直到目标线程完成所有的任务并完全退出

  • 线程自然退出,c++类对象的析构函数能得到执行;调用Terminate线程强行退出,c++类对象的析构函数不能得到正常执行,会造成内存泄漏。而且系统也不会释放线程使用的堆栈!

  • 对于正在运行的线程,如果想要退出,QT5提供了封装好的接口:requestInterruption和isInterruptionRequested。不再需要自定义互斥量和bool类型的退出标记。

  • 有时候我们不希望程序运行到结束,我们需要程序提前终止,这时候我们需要提前退出子线程。
    方法:定义一个停止标志flag,重写stop函数。退出线程直接调用stop函数让flag不满足循环条件,退出循环。

  • 线程同步: 互斥量 :QMutex、 互斥锁:QMutexLocker、 读写锁 :QReadWriteLock 、信号量:QSemaphore 、条件等待:QWaitCondition与QMulex结合,可以使一个线程在满足一定条件时通知其他多个线程,使它们及时作出响应,这样比只使用互斥量效率要高一些。

  • 线程通信:共享内存、信号与槽

  • 进程通信: 共享内存(Value 和 Array)、消息队列(Queue生产者-消费者模型,一个进程生成数据,另一个进程消费数据。)、管道(Pipes)、套接字(Sockets,两台计算机之间网络通信)、文件(Files)
    python多进程与多线程

QProcess

‌QProcess是Qt框架中的一个类,用于在应用程序中执行外部进程。‌
‌1、启动进程‌:支持同步(execute())和异步(start())执行外部程序,可以指定要执行的程序和传递给程序的参数列表。例如,使用start(const QString &program, const QStringList &arguments)函数启动一个外部程序‌
2、分离式启动‌:QProcess还支持分离式启动,即外部程序启动后,主程序可以继续运行,不会被主程序的退出影响。这通过startDetached(const QString &program, const QStringList &arguments)函数实现‌
3、‌进程控制‌:QProcess提供了多种函数来控制进程的启动、等待进程启动和退出、读取进程输出等功能。例如,waitForStarted()会阻塞直到进程启动,waitForFinished()会阻塞直到进程退出‌
4、‌进程通信‌:通过标准输入(stdin)、输出(stdout)和错误输出(stderr)通道与子进程交互。可以通过write()函数向进程的标准输入写入数据,通过read()、readLine()和getChar()函数读取标准输出和错误输出‌
5、状态监控:通过信号(如 started()、finished())实时跟踪进程状态。

# 子进程类
class WorkerProcess(QProcess):  # 继承自QProcess,用于表示子进程
    resultReady = pyqtSignal(str)

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

    def handle_output(self):
        data = self.readAllStandardOutput().data().decode()
        self.resultReady.emit(data)
#主进程       
def start_worker(self):
   self.button.setEnabled(False)
   self.worker_process = WorkerProcess()
   self.worker_process.finished.connect(self.worker_finished)
   self.worker_process.resultReady.connect(self.handle_result)
   self.worker_process.start('python', ['worker.py'])

界面卡死、界面假死

  • UI线程还有一个重要的功能是创建和管理窗体和窗体中的各种控件,负责他们的实时刷新,如果UI线程在处理某个消息的时候耗时特别长,那么后续的消息就无法及时响应,看上去的感觉就是“界面卡死”。
    如何避免界面卡死呢?
    1,负责与用户交互的线程为主线程(简称为UI线程)应该保持顺畅,当UI线程调用的API可能引起阻塞时间超过30毫秒时,就应该考虑使用多线程。所以这种情况下必须使用多线程的方式来解决,即在主界面线程中在启动一个新的子线程,利用该子线程处理比较耗时的操作,然后通过signal-slot机制将子线程的数据反馈到主界面线程中,而且在子线程中不能操作界面。这就是所说的:UI只用来操作UI,子线程只用来处理数据,就是将UI的操作与耗时数据的处理进行分开处理。
    2,在Windows Form中使用多线程时,除了创建控件的线程以外,绝对不要在任何其他线程里面直接调用控件的成员,如果需要,请使用invoke或者BeginInvoke。
  • 界面假死
    热启动是指在电脑已经加电的情况下,同时按下Ctrl、Alt 和Del 键,此时将重新启动机器。它通常是在电脑运行中出现“死机”,即按任意键都没有反应时使用。冷启动是指电脑从断电到通电的这么一个启动过程。
    用户在使用软件的时候,常常会遇到系统提示“程序未响应”问题,于是系统就进入了假死状态,判断计算机假死的最简单的方法是按键盘上的NumLock键,看是否有反应,如果指示灯有反应则说明是假死,没有则死彻底了。
    PyQt5 多线程相关一些例子
    PyQT——多线程(QThread)
    PyQt5 QThread应用
    PyQt5高级界面控件之QThread(十二)
    总结,Qt的子线程写法

线程暂停和继续

  • 使用自定义互斥量和bool类型的暂停标记
    定义两个互斥量,一个互斥量用于保护暂停标记,另一个用于保护具体操作
    暂停标记的保护可以使用互斥锁简化操作
  • 对外提供暂停、继续、是否暂停三个接口
    暂停接口修改暂停标记变量,内部循环前判断暂停变量值,如果需要暂停,则QWaitCondition的wait接口阻塞线程。
    继续接口修改暂停标记标记,同时使用QWaitCondition的wakeall接口唤醒所有等待的线程。
    是否暂停接口可以让客户端知道当前线程是否处于暂停状态。
  • 暂停后如果想退出线程,必须先继续线程才能退出
    pyqt5线程的启动,暂停,恢复与停止

静态函数

静态函数创建控件对象,主函数通过静态方法创建控件,不用主函数中先创建该控件。注意:静态函数参数没有self,函数名不要与类中接口函数名重名。
在这里插入图片描述

父容器

不使用父容器,label就不能添加进去。若要添加只能通过布局管理器,把控件加到布局管理器中


widgetHello = QtWidgets.QWidget()      #创建一个窗体widgetHello,用QWidget类
widgetHello.resize(280,150)            #设置对话框的宽度和高度
LabHello = QtWidgets.QLabel(widgetHello)  #创建一个标签LabHello,父容器为widgetHello

多继承,super得到第一个基类

多继承无法区分新的属性和ui的属性,不能做到界面和逻辑分离

class QmyWidget(QWidget,Ui_FormHello): 
   def __init__(self, parent=None):
      super().__init__(parent)   #调用父类构造函数,创建QWidget窗口

      self.Lab="多继承的QmyWidget"     #新定义的一个变量
      self.setupUi(self)               #self就是QWidget窗体,可以作为参数传给setupUi()
      self.LabHello.setText(self.Lab)  #窗体上的LabHello

MimeData

MimeData用于在不同组件之间传输数据,如剪贴板和拖放操作。QMimeData类是一个数据容器,可以存储各种数据格式的信息,如HTML、文本、URL和图片。
在这里插入图片描述
在这里插入图片描述

QSplashScreen启动画面

用于在应用程序启动时显示一个带有文本和图像的启动画面(Splash Screen),启动画面有两种,一种是静态启动画面,即运行程序显示一个界面(一张图片)。另一种是动态画面,即运行程序显示一个动态画面,通常是一段视频、或一个gif格式图片。

视图QTableView和控件QTableWidget

  • 列表控件QListWidget,树形控件QTreeWidget和表格控件QTableWidget是基于项(item-based)的控件,数据是存储于项中再由对应的控件添加进去并显示的。
  • 列表视图QListView,树形视图QTreeView和表格视图QTableView是基于模型的(model-based),也就是说有关数据的获取或者存储操作都是跟模型有关。==当我们在处理大量数据的时候,采用基于模型的控件可以让程序的处理速度更快,性能更好。==数据模型负责存储和提供数据,而视图部件负责显示和交互。
  • QListWidget、QTreeWidget和QTableWidget分别是对QListView、QTreeView和QTableView封装,是后三者的子类,前三者比后三者使用起来较为简单,不过后三者可以让程序在性能上更好,处理速度更快。
  • 数据源
    QTableView 可以连接到各种不同的数据源,包括数据库、自定义数据结构、CSV 文件等。你可以根据需要实现自定义的数据模型来处理这些数据源。
    QTableWidget 仅适用于小型表格或简单数据,因为它不支持直接连接到复杂的数据源。你需要手动将数据添加到 QTableWidget 中。
  • 性能方面
    QTableView 在处理大量数据时可能具有更好的性能,因为它支持按需加载数据,并且可以优化内存使用。
    QTableWidget 在处理大量数据时可能占用更多内存,因为它将数据直接存储在部件中。对于大型数据集,QTableView 更适合
  • 自定义性:
    QTableView 允许你在视图上应用更高级的自定义,包括自定义单元格渲染、编辑委托、行列排序、过滤等。
    QTableWidget 的自定义性相对有限,适合较简单的表格需求,但可能无法满足复杂的需求。
  • setSelectionBehavior 表格的选择行为。决定了在选择单元格时如何扩展选择区域。常用的选择行为:SelectItems: 选择单个单元格;SelectRows: 选择整行;SelectColumns: 选择整列。
  • selectionMode表格的选择模式,包括:单选模式 (QAbstractItemView.SingleSelection): 用户只能选择一行或一列;多选模式 (QAbstractItemView.MultiSelection): 用户可以选择多行或多列;扩展选择模式 (QAbstractItemView.ExtendedSelection): 允许用户在已有选择的基础上扩展选择区域,例如通过按住 Shift 键进行选择;连续选择模式 (QAbstractItemView.ContiguousSelection): 用户只能选择连续的行或列。
    PyQt4学习笔记2】Qt 的 Model/View 架构
    PyQt5—Qtablewidget控件行或列冻结
    10.6 PyQt5表格介绍【表格控件】-QTableView

QItemSelectionModel 和 QAbstractItemModel (子类QStandardItemModel)

数据流向:Item Model → View (通过 data() 方法)
交互反馈:用户操作 → Selection Model → 通知 View 更新

# 错误理解
model.selectionModel()  # ❌ 不存在此方法
# 正确获取方式
view.selectionModel()   # ✅

# 错误做法(会导致崩溃)
del model
selection_model.clearSelection()  # ❌ model 已被删除
# 正确顺序
selection_model.clearSelection()
del model  # ✅

在这里插入图片描述
在这里插入图片描述

setCentralWidget

一个Qt主窗口应用程序必须有一个中心窗口部件(Central Widget)。当你采用Qt Designer创建主窗口时,默认情况下,系统已经为你创建了一个中心窗口部件,它是子类化QWidget的。每次程序调用setCentralWidget()方法时,先前存在的中心窗口部件将被新的所替换,而且主窗口会销毁原来的部件,无需用户处理。
一旦设置了中心部件,它将填充满主窗口的客户区域(即除去菜单栏、工具栏、状态栏等区域后的空间)‌

其他

  • ObjectName主要是用于外界来访问内部的控件成员的,如果外界不需要访问这个成员,则理论上无需设置它的ObjectName。
  • 许多QWidget对象都支持拖拽动作,允许拖拽的控件必须设置QWidget.setDragEnabled()为True。
    setCheckable(true)为属性,表示可以选中
    setChecked(true)为属性的值,表示已经选中,可设置按钮初始状态
    setPlaceholderText()方法用于在输入框显示浅灰色的提示文本
    setEchoMode(QLineEdit.Password)将普通输入框中的文字变成原点
    setValidator正则验证器(QRegExpValidator字符型,QIntValidator整型,QDoubleValidator浮点型)
    ‌setAutoExclusive‌是QRadioButton默认是自动互斥的,这意味着在同一父窗口中的多个QRadioButton只能选择一个。
    ‌setTristate‌是QCheckBox控件的一个方法,用于设置复选框是否支持三态(未选中、选中、部分选中)。
    QButtonGroup 提供了一种简单的方式来实现互斥逻辑(Qframe也可实现该功能)。designer中没有这个控件,可以选择必要的按钮,右键进行创建。
    button1.setAutoExclusive(True) 控制同一父容器下的按钮是否自动形成互斥组

QTextBrowser

用于显示富文本内容和超链接。QTextBrowser继承于QTextEdit的只读模式,提供了一些额外的功能,使得显示和浏览文本内容变得更加方便和灵活。它支持显示格式丰富的文本,包括粗体、斜体、下划线、超链接等。

QColor

1、创建方式
在这里插入图片描述
2、大小写不敏感:QColor(“Red”)、QColor(“RED”) 和 QColor(“red”) 效果相同。
3、若名称无效(如拼写错误),QColor 会默认创建黑色 (#000000),但可通过 .isValid() 检查
4、QColor 支持的颜色名称遵循 SVG 1.0 颜色规范,包含 140+ 种预定义颜色。完整列表可参考 SVG颜色名称表


aliceblue	rgb(240, 248, 255)
antiquewhite	rgb(250, 235, 215)
aqua	rgb( 0, 255, 255)
aquamarine	rgb(127, 255, 212)
azure	rgb(240, 255, 255)
beige	rgb(245, 245, 220)
bisque	rgb(255, 228, 196)
black	rgb( 0, 0, 0)
blanchedalmond	rgb(255, 235, 205)
blue	rgb( 0, 0, 255)
blueviolet	rgb(138, 43, 226)
brown	rgb(165, 42, 42)
burlywood	rgb(222, 184, 135)
cadetblue	rgb( 95, 158, 160)
chartreuse	rgb(127, 255, 0)
chocolate	rgb(210, 105, 30)
coral	rgb(255, 127, 80)
cornflowerblue	rgb(100, 149, 237)
cornsilk	rgb(255, 248, 220)
crimson	rgb(220, 20, 60)
cyan	rgb( 0, 255, 255)
darkblue	rgb( 0, 0, 139)
darkcyan	rgb( 0, 139, 139)
darkgoldenrod	rgb(184, 134, 11)
darkgray	rgb(169, 169, 169)
darkgreen	rgb( 0, 100, 0)
darkgrey	rgb(169, 169, 169)
darkkhaki	rgb(189, 183, 107)
darkmagenta	rgb(139, 0, 139)
darkolivegreen	rgb( 85, 107, 47)
darkorange	rgb(255, 140, 0)
darkorchid	rgb(153, 50, 204)
darkred	rgb(139, 0, 0)
darksalmon	rgb(233, 150, 122)
darkseagreen	rgb(143, 188, 143)
darkslateblue	rgb( 72, 61, 139)
darkslategray	rgb( 47, 79, 79)
darkslategrey	rgb( 47, 79, 79)
darkturquoise	rgb( 0, 206, 209)
darkviolet	rgb(148, 0, 211)
deeppink	rgb(255, 20, 147)
deepskyblue	rgb( 0, 191, 255)
dimgray	rgb(105, 105, 105)
dimgrey	rgb(105, 105, 105)
dodgerblue	rgb( 30, 144, 255)
firebrick	rgb(178, 34, 34)
floralwhite	rgb(255, 250, 240)
forestgreen	rgb( 34, 139, 34)
fuchsia	rgb(255, 0, 255)
gainsboro	rgb(220, 220, 220)
ghostwhite	rgb(248, 248, 255)
gold	rgb(255, 215, 0)
goldenrod	rgb(218, 165, 32)
gray	rgb(128, 128, 128)
grey	rgb(128, 128, 128)
green	rgb( 0, 128, 0)
greenyellow	rgb(173, 255, 47)
honeydew	rgb(240, 255, 240)
hotpink	rgb(255, 105, 180)
indianred	rgb(205, 92, 92)
indigo	rgb( 75, 0, 130)
ivory	rgb(255, 255, 240)
khaki	rgb(240, 230, 140)
lavender	rgb(230, 230, 250)
lavenderblush	rgb(255, 240, 245)
lawngreen	rgb(124, 252, 0)
lemonchiffon	rgb(255, 250, 205)
lightblue	rgb(173, 216, 230)
lightcoral	rgb(240, 128, 128)
lightcyan	rgb(224, 255, 255)
lightgoldenrodyellow	rgb(250, 250, 210)
lightgray	rgb(211, 211, 211)
lightgreen	rgb(144, 238, 144)
lightgrey	rgb(211, 211, 211)
    	
lightpink	rgb(255, 182, 193)
lightsalmon	rgb(255, 160, 122)
lightseagreen	rgb( 32, 178, 170)
lightskyblue	rgb(135, 206, 250)
lightslategray	rgb(119, 136, 153)
lightslategrey	rgb(119, 136, 153)
lightsteelblue	rgb(176, 196, 222)
lightyellow	rgb(255, 255, 224)
lime	rgb( 0, 255, 0)
limegreen	rgb( 50, 205, 50)
linen	rgb(250, 240, 230)
magenta	rgb(255, 0, 255)
maroon	rgb(128, 0, 0)
mediumaquamarine	rgb(102, 205, 170)
mediumblue	rgb( 0, 0, 205)
mediumorchid	rgb(186, 85, 211)
mediumpurple	rgb(147, 112, 219)
mediumseagreen	rgb( 60, 179, 113)
mediumslateblue	rgb(123, 104, 238)
mediumspringgreen	rgb( 0, 250, 154)
mediumturquoise	rgb( 72, 209, 204)
mediumvioletred	rgb(199, 21, 133)
midnightblue	rgb( 25, 25, 112)
mintcream	rgb(245, 255, 250)
mistyrose	rgb(255, 228, 225)
moccasin	rgb(255, 228, 181)
navajowhite	rgb(255, 222, 173)
navy	rgb( 0, 0, 128)
oldlace	rgb(253, 245, 230)
olive	rgb(128, 128, 0)
olivedrab	rgb(107, 142, 35)
orange	rgb(255, 165, 0)
orangered	rgb(255, 69, 0)
orchid	rgb(218, 112, 214)
palegoldenrod	rgb(238, 232, 170)
palegreen	rgb(152, 251, 152)
paleturquoise	rgb(175, 238, 238)
palevioletred	rgb(219, 112, 147)
papayawhip	rgb(255, 239, 213)
peachpuff	rgb(255, 218, 185)
peru	rgb(205, 133, 63)
pink	rgb(255, 192, 203)
plum	rgb(221, 160, 221)
powderblue	rgb(176, 224, 230)
purple	rgb(128, 0, 128)
red	rgb(255, 0, 0)
rosybrown	rgb(188, 143, 143)
royalblue	rgb( 65, 105, 225)
saddlebrown	rgb(139, 69, 19)
salmon	rgb(250, 128, 114)
sandybrown	rgb(244, 164, 96)
seagreen	rgb( 46, 139, 87)
seashell	rgb(255, 245, 238)
sienna	rgb(160, 82, 45)
silver	rgb(192, 192, 192)
skyblue	rgb(135, 206, 235)
slateblue	rgb(106, 90, 205)
slategray	rgb(112, 128, 144)
slategrey	rgb(112, 128, 144)
snow	rgb(255, 250, 250)
springgreen	rgb( 0, 255, 127)
steelblue	rgb( 70, 130, 180)
tan	rgb(210, 180, 140)
teal	rgb( 0, 128, 128)
thistle	rgb(216, 191, 216)
tomato	rgb(255, 99, 71)
turquoise	rgb( 64, 224, 208)
violet	rgb(238, 130, 238)
wheat	rgb(245, 222, 179)
white	rgb(255, 255, 255)
whitesmoke	rgb(245, 245, 245)
yellow	rgb(255, 255, 0)
yellowgreen	rgb(154, 205, 50)

文件操作QFile、QFileInfo、QTemporaryFile、QSaveFile

简单配置 → QSettings 或 JSON
结构化数据 → SQLite
大型二进制数据 → 文件系统 + 缓存
只读资源 → Qt资源系统
临时数据 → QCache或QTemporaryFile

【QT】Qt 文件操作

QSettings注册表

开发软件过程中,都会缓存一些信息到本地,可以使用轻量级数据库sqlite,也可以操作注册表、读写配置文件。如果不指定作用域(Scope),它会根据以下规则操作注册表:
用户级配置:HKEY_CURRENT_USER\Software<组织名><应用名>
系统级配置:HKEY_LOCAL_MACHINE\Software<组织名><应用名>

import sys
from PyQt5.QtWidgets import  QApplication, QMainWindow,QActionGroup  
from PyQt5.QtGui import  QTextCharFormat, QFont
from PyQt5.QtCore import (Qt, pyqtSlot,QCoreApplication,
                  QTranslator,QSettings,QT_TRANSLATE_NOOP)
app = QApplication(sys.argv)    #创建GUI应用程序

# 读取注册表里的语言设置
QCoreApplication.setOrganizationName("mySoft")
QCoreApplication.setApplicationName("Demo11_1")

##organization="mySoft"  #用于注册表
##appName="Demo11_1" #HKEY_CURRENT_USER/Software/mySoft/Demo11_1
regSettings=QSettings(QCoreApplication.organizationName(),
                       QCoreApplication.applicationName())  #创建
Language=regSettings.value("Language","CN")  #读取Language键的值,缺省"EN"
trans=QTranslator()
if Language=="EN":
      trans.load("appLang_EN.qm")
else:
      trans.load("appLang_CN.qm")
QCoreApplication.installTranslator(trans)

form=QmyMainWindow()                #创建窗体
form.setTranslator(trans,Language)  #赋值给QmyMainWindow的类变量translator
form.show()
sys.exit(app.exec_())

自启动和文件关联

def set_auto_startup(enabled):
    settings = QSettings(
        r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
        QSettings.NativeFormat
    )
    if enabled:
        app_path = os.path.abspath(sys.argv[0])
        settings.setValue("MyApp", f'"{app_path}" --minimized')
    else:
        settings.remove("MyApp")
def register_file_association(ext, prog_id, app_path):
    # 注册扩展名
    ext_settings = QSettings(
        f"HKEY_CLASSES_ROOT\\.{ext}",
        QSettings.NativeFormat
    )
    ext_settings.setValue(".", prog_id)

    # 注册 ProgID 的打开命令
    cmd_settings = QSettings(
        f"HKEY_CLASSES_ROOT\\{prog_id}\\shell\\open\\command",
        QSettings.NativeFormat
    )
    cmd_settings.setValue(".", f'"{app_path}" "%1"')

进行软件的设置状态数据储存与初始化
QSettings读写注册表、配置文件
PyQt5快速上手基础篇10-QSettings用法

Win注册表

Windows注册表(Registry)是操作系统的核心数据库,存储了硬件、软件、用户配置和系统策略等关键信息。Windows使用注册表(如 HKEY_CLASSES_ROOT.docx)关联扩展名到对应的应用程序路径。
当用户双击文档时:
1、系统查询关联程序:操作系统根据扩展名查找默认程序。
2、启动程序并传递参数:系统执行关联程序的路径,并将文档路径作为命令行参数传递。例如:“C:\Program Files\Microsoft Office\Word.exe” “C:\Users\Example.docx”

  • 注册表的结构
    注册表采用树形分层结构,包含多个根键(Hive Keys)、子键(Subkeys)和键值(Values):
    根键(顶级节点):
    HKEY_CLASSES_ROOT (HKCR)管理文件关联、COM组件和快捷方式。
    HKEY_CURRENT_USER (HKCU)存储当前用户的个性化设置(如桌面、软件偏好)。
    HKEY_LOCAL_MACHINE (HKLM)保存全局硬件、驱动和系统级配置(所有用户共享)。
    HKEY_USERS (HKU)包含所有用户配置的原始数据。
    HKEY_CURRENT_CONFIG (HKCC)当前硬件配置的实时信息(如显示器分辨率)。

  • 键值类型:
    REG_SZ:字符串(文本值)。
    REG_DWORD:32位整数(常用于开关设置)。
    REG_BINARY:二进制数据(如硬件配置)。
    REG_EXPAND_SZ:含环境变量的字符串(如%SystemRoot%)。
    REG_MULTI_SZ:多行字符串。

  • 文件关联的核心机制
    (1)扩展名与程序的绑定
    文件扩展名:如 .txt、.docx、.mp3,是文件类型的标识符。
    默认程序:每个扩展名关联到特定的应用程序(如 .txt → 记事本)。
    (2)注册表的核心路径
    Windows通过注册表的 HKEY_CLASSES_ROOT(HKCR)分支管理文件关联:
    扩展名键:HKCR.ext(如 HKCR.txt)指向一个文件类型标识符(ProgID)。
    ProgID键:HKCR<ProgID>(如 HKCR\txtfile)定义该文件类型的详细信息,包括图标、右键菜单和默认程序路径。
    (3)关联过程示例
    用户双击 .txt 文件:系统查询 HKCR.txt,发现其默认值为 txtfile。进一步查找 HKCR\txtfile\shell\open\command,获取程序路径(如 Notepad.exe “%1”)。
    启动程序:系统执行命令,传递文件路径给关联程序。

  • 参数传递的核心机制
    1)命令行参数的生成
    注册表中的命令模板:
    文件关联的最终执行命令存储在注册表的 HKCR<ProgID>\shell\open\command 键值中,例如:“C:\Program Files\Notepad++\notepad++.exe” “%1”
    %1 表示用户双击文件的完整路径(如 C:\Users\Test\文件.txt)。系统会自动将 %1 替换为实际文件路径,并传递给程序。
    2)路径格式化的关键规则
    引号包裹路径:
    若路径包含空格或特殊字符(如 C:\Program Files\),需用双引号包裹路径,否则程序可能因参数截断而报错。(路径含空格时无法识别)
    环境变量扩展:
    使用 %SystemRoot% 或 %USERPROFILE% 等环境变量时,需确保命令模板支持扩展。示例:“%SystemRoot%\system32\notepad.exe” “%1”
    3)特殊参数符号
    %*:传递所有参数(如拖放多个文件到程序图标时)。
    %0:传递程序自身路径(罕见使用)。

  • 程序如何接收路径参数
    程序通过 main() 或 WinMain() 函数的 argv[] 参数接收路径。例如:
    int main(int argc, char *argv[]) {
    if (argc > 1) {
    // argv[1] 包含文件路径(如 “C:\Test\file.txt”)
    }
    }

  • 关联程序未正确接收路径
    检查注册表 command 键值是否正确(包括引号)。
    通过命令行手动测试:“C:\Program Files\App\app.exe” “C:\Test\file.txt”
    使用 Process Monitor 工具监控程序启动时的参数传递。

QSplitter拆分器

SetStretchFactor()用于设定可伸缩控件比例,它的第一个参数指定设置的控件序号,控件序号按插入的先后次序进行编号;第二个参数为大于0的值表示此控件为可伸缩控件比例。
splitter.setSizes([300, 700]) # 左右比例为 300:700,若设置的总和 ≠ 拆分器实际宽度/高度,Qt 会按比例缩放各部件尺寸。
setOpaqueResize(true); 设定在拖拽分割条时,是否实时更新。若为true,则实时更新;否则在拖拽时显示一条虚线。
childrenCollapsible 控制子部件是否可被折叠至零尺寸(默认true)‌‌
handleWidth 设置分割条的视觉宽度(单位:像素)

QSqlQueryModel、QSqlTableMode

QSqlQueryModel提供了一个sql查询结果的只读数据模型。它从查询QSqlQueryModel获取数据。可以方便的用于在QListView, QTableView, QTreeView等各种view上展示数据。但它是只读的,不能编辑。

QSqlTableMode继承于QSqlQueryModel,比QSqlQueryModel的限制在于不能是任意sql语句,只是对单个数据表操作。
拓展在于在各种view上展示表格数据的同时,还允许用户进行编辑操作。

窗口部件基类QWidget, QMainWindow, QDialog

  • QWidget有两个派生类QDialog和QMainWindow,这三个类都可以用来创建窗口。

  • QWidget作为基类,自然可以应用在任何场合,但一切都需要自己动手,白手起家,唯一的好处是想怎么干就怎么干。

  • QDialog是对话框窗口的基类,可用来执行短期任务,或者与用户进行互动。对话框窗口可以是模态的,也可以是非模态的,没有菜单栏、工具栏、状态栏等。
    通过Dialog.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)可以关掉对话窗口右上角的问号。
    QDialog是对话框类,它有以下3个内建的槽函数,这3个槽函数都可以关闭对话框,但是表示的对话框的返回值不同
    · accept(),功能是关闭对话框,表示肯定的选择,例如“确定”。
    · reject(),功能是关闭对话框,表示否定的选择,例如“取消”。
    · close(),功能是关闭对话框。

  • QMainWindow类是GUI程序的主窗口类,提供了构建用户应用程序界面的框架,包括MenuBar、ToolBar、StatusBar、DockWidget、CentralWidget等。因为QMainWindow类有自己的布局,不能像前面的例子那样调用窗口的setLayout方法布局,因此也就不能嵌入到其他窗口,只能作为顶层窗口。如果要对QMainWindow类创建的窗口内的部件布局,应该调用中央部件区的setLayout方法。
    在这里插入图片描述

窗体属性、窗体标志、窗口状态、窗口模态

setAttribute()函数用于设置窗体的一些属性
在这里插入图片描述
setWindowFlags()窗体标志,同时设置多个;setWindowFlag()用于一次设置一个
在这里插入图片描述
setWindowState()函数使窗口处于最小化、最大化
在这里插入图片描述
setWindowModality()函数用于设置窗口的模态
在这里插入图片描述

窗口中控件的坐标系

在这里插入图片描述

x()——得到窗口左上角在显示屏屏幕上的x坐标;
y()——得到窗口左上角在显示屏屏幕上的y坐标;
pos()——得到窗口左上角在显示屏屏幕上的x和y坐标,类型为QPoint();
frameGeometry().width()——得到窗口的宽度;
frameGeometry().height()——得到窗口的长度;
frameGeometry().x()——即x(),得到窗口左上角在显示屏屏幕上的x坐标;
frameGeometry().y()——即y(),得到窗口左上角在显示屏屏幕上的y坐标;
frameGeometry()——即pos(),得到窗口左上角在显示屏屏幕上的x和y坐标,以及窗口的宽度和长度,类型为QRect();
geometry().x()——得到客户区左上角在显示屏屏幕上的x坐标;
geometry().y()——得到客户区左上角在显示屏屏幕上的y坐标;
geometry()——得到客户区左上角在显示屏屏幕上的x和y坐标,以及客户区的宽度和长度,类型为QRect();
width()——得到客户区的宽度;
height()——得到客户区的长度;
geometry().width()——得到客户区的宽度;
geometry().height()——得到客户区的长度;

子窗口的位置是基于父窗口的坐标体系来确定的,也就是说通过父窗口左上角的坐标点来确定自己的位置,Qt中窗口显示的时候使用的相对坐标,相对于自己的父窗口,将子窗口移动到父窗口的某个位置。

注:通过geometry()和frameGeometry()获取坐标的相关方法需要在窗口调用show()方法之后才能使用,否则获取的将是无用数据
ui.btnTest.setGeometry(10/ 2, 10 / 2, Wbtn, Hbtn)pyqt无法启动或者软件闪退,因为(/)除法生成小数,setGeometry参数要求整数,需要使用(//)整除

QApplication、QGuiApplication、QCoreApplication

一个QApplication实例,其实就是Singleton模式,QApplication的主要职责如下:
1、使用用户的桌面设置进行初始化,这些设置如palette()、font()、doubleClickInterval(),然后跟踪这些属性的变化,如用户通过某种配置面板修改了全局桌面设置。
2、处理事件,从窗口系统接收事件并派发到相应的Widget,使用sendEvent()和postEvent()函数可以派发事件。
3、处理命令行参数,设置内部状态。
4、定义GUI外观,外观由QStyle对象包装,运行时通过setStyle()函数进行设置。
5、设置颜色分配规则,对应的函数为setColorSpec()。
6、本地化字符串,函数为translate()。
7、提供了一些有用的对象,如desktop()、clipboard()函数。
8、知道Widget及Window,相应的函数为widgetAt()、topLevelWidgets()、closeAllWindows()。
9、管理鼠标光标,函数为setOverrideCursor()。
【QT】QApplication简介

QWidget 模态

  • 模态窗口会阻止其他窗口的输入型事件,但是模态窗口的子窗口不会被限制。通过QWidget 的 setWindowModality() 函数设置,有三种类型:
    在这里插入图片描述

QDialog 模态

QDialog 是 QWidget 的派生类,不同于 QWidget 的默认无模态,QDialog 有三种情况:在这里插入图片描述

  • 从字面上看,show()即可以显示非模式也可以显示模式对话框(设置modal值)。当modal=true的时候是否跟exec()就一样了呢?
    经过测试,还是有区别的。
    使用show(),虽然在对话框弹出的时候,程序的其它操作(按钮、窗口切换等)都失效了;但是程序仍然在调用对话框之后,马上返回继续执行后面的代码。这样,你就不会得到窗口的返回值。以这个来看,show()只能算是“半模式”。
    而使用exec(),在调用之后,程序就被锁定在原地。等待窗口的关闭。
    实际上,QDialog的show()函数来自其父类QWidget。而exec()则是自己的。

QFrame容器控件

QFrame容器控件与QWidget容器控件的区别:QFrame继承至QWidget,QFrame可设置框架形状、框架阴影
Box内容四周绘制一个边框,Panel绘制一个面板有凸起、凹陷效果,StyledPanel绘制面板有凸起、凹陷,效果依赖当前的GUI样式。
Plain没有3D效果,Raised凸起的3D效果,Sunken凹陷的3D效果。
lineWidth 是边框边界线的宽度,midLineWidth是边框额外插入的一条线的宽度,为了形成3D效果;
PyQt5 QFrame
PyQt5中的QFrame控件
在这里插入图片描述

QPainterPath

利用QPainterPath绘制简单图形,QPainterPath 类为QPainter类提供了一个存储容器,里面包含了所要绘制的内容的集合及绘制的顺序,如长方形、多边形、曲线等各种任意图形。当需要绘制此预先存储在QPainterPath对象中的内容时,只需调用QPainter类的drawPathQ函数即可。

QPainterPath 对象的当前点自动处在上一部分图形内容的结束点上,若下一部分图形的起点不在此结束点,则需调用moveTo()函数将当前点移动到下一部分图形的起点。

默认的起点在(0,0),在lineTo()之后,会将path的自动起点位置移到lineTo的点。addRect()或者addRoundedRect()之后会自动将起点移到Rect的左上角顶点

  • QPainterPath裁剪图像
from PyQt5 import QtCore, QtGui

if __name__ == '__main__':
    image = QtGui.QImage('input.png')
    output = QtGui.QImage(image.size(), QtGui.QImage.Format_ARGB32)
    output.fill(QtCore.Qt.transparent)
    painter = QtGui.QPainter(output)

    points = [(444, 203), (623, 243), (691, 177), (581, 26), (482, 42)]
    polygon = QtGui.QPolygonF([QtCore.QPointF(*point) for point in points])

    path = QtGui.QPainterPath()
    path.addPolygon(polygon)
    painter.setClipPath(path)
    painter.drawImage(QtCore.QPoint(), image)
    painter.end()
    output.save('out.png')

绘图QPainter 和QGraphicsView

1、对于图形的绘制,可以使用 QPainter 实现普通二维图形的绘制,绘图要在painEvent() 方法中实现。在QPainter 对象的begin() 与end() 方法间绘图代码。其本质绘制的图形是位图,这种方法更适合于绘制复杂度不高的固定图形,并且不能实现图项的选择、编辑、拖放、修改等交互功能。
2、painEvent() 绘图事件不用手动调用,通过重写父类虚函数之后会自动调用。绘制的自动触发机制:

  • 窗口第一次显示时
  • 窗口大小调整时
  • 窗口切换或遮挡

手动触发机制:在程序中使用update或者repaint进行重绘
3、自Qt4开始,控件就自带双缓冲绘图功能来消除闪烁问题了,所以没有必要再在paintEvent()事件函数中再编写双缓冲代码。

4、Painter中setCapStyle()设置笔端样式,setJoinStyle()设置线条连接方式
5、painter.save()函数会将当前的所有状态(如笔、刷子、字体、变换矩阵等)压入一个栈中,而painter.restore()函数则会从栈中弹出最近保存的状态,并将QPainter的状态恢复为该状态‌。这是一种很方便的方式,可以让你临时改变状态,然后在不需要这些改变的时候,轻松恢复到原来的状态。

5、QPainter采用面向过程的描述方式绘图;GraphicsView采用面向对象的描述方式绘图。
6、一般使用QLabel控件来显示图片。但是,如果要使用很多图片怎么办?难道要实例化很多个QLabel控件来一一显示?PyQt5中的图形视图QGraphicsView可以让我们管理大量的自定义2D图元并与之交互。
7、对于需要绘制大量的、需要交互的图形,可使用Graphics View绘图架构,它是一种基于图形项(Graphics Item)的模型/视图模式,这种方式可以在一个场景中绘制大量图元项,且每个图元项都是可选择、可交互的。
8、场景的边界矩形是通过调用setSceneRect()设置的。项目可以放置在场景的任何位置,默认情况下,场景的大小是无限的。场景矩形仅用于内部记账,维护场景的项索引。如果场景rect未设置,QGraphicScene将使用itemsBoundingRect()返回的所有项的边界区域作为场景矩形。但是,itemsBoundingRect()是一个相对耗时的函数,因为它通过收集场景中每个项目的位置信息来操作。因此,在大型场景上操作时,应始终设置场景矩形。

python之pyQt5实例:GraphicsView控件
实战PyQt5: 123-详解QPainter绘图
pyqt使用graphicsView显示图片
PyQt 教程 —— 图像类及图像相关基础类介绍
使用graphicsView的完善的画图及保存方案
pyqt5 GraphicsView 加载图片 鼠标托画填充路径并保存成图片
如何在pyqt中使用 QGraphicsView 实现图片查看器
Qt中QGraphics类坐标映射关系详解
QGraphicsView 如何让图形大小适配窗口
【PyQt5】 实现图元(QGraphicsItem)的建立、操作和连接
Qt之QGraphicsView进阶篇
QGraphicsView使用详解

4个常用的图像类QPixmap、QImage、QPicture、QBitmap

  • QPixmap 的作用是加载并呈现本地图像,而图像的呈现本质上也是通过绘图方式实现的
  • QImage提供了一个与硬件无关的图像表示函数,可以用于图片的像素级访问;对高分辨率图像频繁调用 toImage() 可能导致性能瓶颈。仅在需要像素操作时转换,避免实时处理。性能优化替代方案:使用 QImage 的 bits() 直接操作内存(需配合 NumPy 加速)
ptr = image.bits()
ptr.setsize(image.byteCount())
pixels = np.frombuffer(ptr, dtype=np.uint8).reshape(image.height(), image.width(), 4)#numpy.frombuffer 函数用于从缓冲区(如字节、字节数组或其他支持缓冲区接口的对象)创建一个 NumPy 数组。
pixels[:, :, :3] = 255 - pixels[:, :, :3]  # 反转 RGB 通道
  • QPicture是一个绘图设备类,它继承自QPainter类,可以使用QPainter的begin()函数在QPicture上绘图,使用end()函数结束绘图,使用QPicture的save()函数将QPainter所使用过的绘图指令保存到文件中;
  • QBitmap是一个继承自QPixmap的简单类,它提供了1bit深度的二值图像的类,QBitmap提供的单色图像可以用来制作游标(QCursor)或者笔刷(QBrush)。
    一篇全面的关于Qt对图像数据的操作总结
    pyqt5 QImage QPixmap Opencv图像 相互转换

关于图表PyQtGraph、Matplotlib、PyQtChart

  • 三者都是独立库,需要单独安装

  • PyQtGraph(基于Qt和NumPy开发)要比Matplotlib快的多

  • matplotlib画静态图可以,大数据实时用pyqtgraph,小数据量可以用qchart

  • Matplotlib的目标更多是制作出版质量的图形,而pyqtgraph则用于数据采集和分析应用。

  • Matplotlib并不包含许多pyqtgraph的功能,如图像交互,体绘制,参数树,流程图等。

  • FigureCanvasQTAgg‌ 是 Matplotlib 库中用于将绘图嵌入 PyQt5 或 PySide2 图形界面中的一个类。它允许用户将 Matplotlib 绘制的图形直接嵌入到 Qt 应用程序中,从而创建丰富的交互式图形界面

  • PyQtChart可以绘制折线图、散点图、柱状图、饼图、极坐标图、蜡烛图、面积图

  • PyQtChart中可以使用setRubberBand(QChart.RectangleRubberBand)橡皮筋模式,这个功能允许用户通过鼠标选择图表的一个区域进行缩放。
    pyqtgraph官网
    PyQtGraph案例
    在这里插入图片描述

在这里插入图片描述

OpenGL(Open Graphics Library)

一个跨平台、跨语言的图形编程接口(API),与编程语言无关(C/C++、Python、Java 等均可调用),专门用于渲染 2D/3D 图形。它赋予开发者直接操控 GPU 的能力。集显可以运行 OpenGL,但需确认支持的版本和驱动。
opengl可以大大提高绘制曲线的速度,一般会提高上百倍,但开启opengl加速后,序列的某些设置就是无效的,如不能设置线型只能是实线,不能显示数据点,不能设置透明度,不能显示数据点标签,但仍可以设置线条的颜色和线宽。
在这里插入图片描述

QT资源系统

Qt 资源系统(Qt Resource System)是一种将图片、数据存储在二进制文件中的一套系统。一般我们在程序中调用一张图片作为某个按钮的图标,如果替换成另一张同名的图片,那么程序运行时会加载新的图标。有这么一种情况,开发者不希望这些图标被修改或者图标文件丢了程序界面也就不能正常显示。
怎么办呢?我们可以把这些图片存储在可执行文件中,即使删除了文件夹中的图标也不会影响界面图标的加载,因为图标数据已经以静态数据的方式保存在可执行文件中了。当然,代价就是编译出的可执行文件容量会增加。克服这个缺点的办法就是动态加载资源
QPixmap(“:/image.png”) 是如何使用资源的示例。注意路径前的冒号和斜杠(😕),这是访问打包资源的标准方式。
Qt 资源系统
在PyQt中使用qrc/rcc资源系统
png转ico
多层极生成ico
阿里巴巴图标库iconfont,种类多,可自设颜色
打包后图标模糊的问题

软件开机自启动

软件写注册表设置开机自启动
开机启动C++实现
python项目实战:实现电脑开机自启动某软件

QPalette(调色板)

每个窗体和控件都包含一个QPalette对象,在显示时,对其做相应的设置即可。
修改QApplication的调色板, 会影响到该应用程序的所有窗口部件
对一个窗口部件的调色板作了修改后,再对其父窗口部件调色板进行修改, 不会影响到该窗口部件的调色板
QPalette 调色板 与QPainter 画板区别
pyqt5学习笔记3: 使用QPalette(调色板)

设置窗口背景

1)使用QSS设置窗口背景
#设置对象名称
win.setObjectName("MainWindow")
#todo 1 设置窗口背景图片
win.setStyleSheet("#MainWindow{border-image:url(./images/python.jpg);}")
#todo 2 设置窗口背景色
#win.setStyleSheet("#MainWindow{background-color: yellow}")2)使用QPalette设置窗口背景
当使用QPalette(调试板)来设置背景图片时,需要考虑背景图片的尺寸
当背景图片的宽度高度大于窗口的宽度高度时,背景图片会平铺整个背景
当背景图片宽度高度小于窗口的宽度高度时,则会加载多个背景图片
palette = QPalette()
palette.setBrush(QPalette.Background, QBrush(QPixmap("./images/python.jpg")))
win.setPalette(palette)

# todo 1 当背景图片的宽度和高度大于窗口的宽度和高度时
# win.resize(460,  255 )
# # todo 2 当背景图片的宽度和高度小于窗口的宽度和高度时
# win.resize(800, 600)3)实现PainEvent,使用QPainter绘制背景
    def paintEvent(self, event):
        painter = QPainter(self)
        #todo 1 设置背景颜色
        painter.setBrush(Qt.green)
        painter.drawRect(self.rect())

        # #todo 2 设置背景图片,平铺到整个窗口,随着窗口改变而改变
        # pixmap = QPixmap("./images/screen1.jpg")
        # painter.drawPixmap(self.rect(), pixmap)

PyQt5图形和特效之设置窗口背景(六)

环形进度条

Python3 PyQt5自定义圆环进度条(带渐变效果)用多线程实现传参数

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值