PyQt5.QtCore模块提供了非 GUI 的核心功能,是构建任何 PyQt5 应用(无论是否包含图形界面)都必不可少的基础模块。与提供具体控件的QtWidgets模块不同,QtCore主要负责提供应用所需的基础设施,如事件循环、对象间通信、多线程、文件和目录操作、时间日期处理等。
核心类与功能
QtCore模块包含了许多重要的类和工具,以下是其中最核心的部分:
1、元对象系统与信号槽:QObject与通信机制
QtCore模块为 PyQt5 提供了强大的元对象系统(Meta-Object System)。QObject类是所有 Qt 对象的基类,它赋予了对象使用信号与槽(Signals & Slots) 进行通信的能力。
自定义信号:通过
pyqtSignal()在QObject的子类中定义。信号可以携带任意数量的参数。自定义槽函数:任何普通的 Python 函数都可以作为槽。使用
@pyqtSlot()装饰器可以明确标识槽函数,并进行参数类型检查。信号与槽的连接:使用
信号.connect(槽函数)进行连接。一个信号可以连接多个槽,一个槽也可以被多个信号连接。信号甚至可以连接另一个信号。
2、应用与事件循环:QCoreApplication
这是所有 Qt 应用的核心,负责管理主事件循环(Event Loop)。QApplication类(来自QtWidgets)就是它的子类,专门为 GUI 应用提供了额外功能。
核心作用:
app.exec_()会启动主事件循环,让程序持续运行并等待和分发事件(如鼠标点击、键盘输入、定时器事件等)。无 GUI 应用:对于纯控制台应用或无界面程序,可以直接使用
QCoreApplication。
3、多线程与并发:QThread
QThread是 PyQt5 中实现多线程的核心类,用于将耗时任务移出主线程,防止界面“卡死”。
使用方法:通常有两种方式:
继承QThread:创建QThread的子类,并重写其run()方法,将耗时任务放在run()中执行。
moveToThread():创建一个继承自QObject的工作类,将其实例通过moveToThread()移动到QThread对象中执行。这是官方更推荐的方式,因为它更灵活。
关键原则:子线程中绝不能直接操作 UI 元素,必须通过信号与槽机制将数据传回主线程进行更新。
4、定时器:QTimer
QTimer类提供了定时器功能,可以周期性或单次地触发任务
核心信号:timeout() 信号在定时器超时时被发射
常用方法:
start(msec):启动定时器,设置间隔(毫秒)。stop():停止定时器。setSingleShot(True):设置为单次触发模式。QTimer.singleShot(msec, callable):静态方法,用于创建单次定时器
5、文件与目录操作:QFile与QDir
QtCore提供了跨平台的文件和目录操作类。
QFile:用于读写文件,支持二进制和文本模式。常与QTextStream配合进行方便的文本读写。QDir:用于操作目录,如创建、删除、遍历目录内容,获取文件列表等。QFileInfo:提供文件的详细信息,如大小、权限、修改时间等。
6、数据处理与工具类
QtCore还提供了许多用于数据处理和系统交互的工具类。
时间日期:
QDate、QTime、QDateTime用于处理日期和时间。字节数组:
QByteArray用于处理原始二进制数据。配置管理:
QSettings提供了跨平台的应用程序设置存储和恢复功能。它可以以统一的方式在 Windows 注册表、macOS 的 plist 文件或 Unix 的 INI 文件中存储配置。进程管理:
QProcess用于启动和控制外部程序。
---------------------------------------------------------------------------------------------------------------------------------
常见用法
1、自定义信号与槽
from PyQt5.QtCore import QObject, pyqtSignal
class Worker(QObject):
# 1. 定义信号,可携带参数
finished = pyqtSignal(str)
progress = pyqtSignal(int)
def do_work(self):
# 2. 在合适的时机发射信号
self.progress.emit(0)
# ... 执行耗时操作 ...
self.progress.emit(100)
self.finished.emit("任务完成!")
2、使用QThread处理耗时任务
from PyQt5.QtCore import QThread, pyqtSignal
class WorkerThread(QThread):
result = pyqtSignal(str)
def run(self):
# 耗时操作
import time
time.sleep(5)
self.result.emit("计算完成!")
# 在主线程中使用
self.thread = WorkerThread()
self.thread.result.connect(self.update_ui) # update_ui 是主线程的槽函数
self.thread.start()
这样就能避免阻塞主线程
3、使用QTimer创建定时任务
from PyQt5.QtCore import QTimer
# 创建定时器
self.timer = QTimer()
# 连接超时信号
self.timer.timeout.connect(self.update_time) # update_time 是槽函数
# 每1000毫秒触发一次
self.timer.start(1000) # [reference:63][reference:64]
4、使用QSettings保存和加载设置
from PyQt5.QtCore import QSettings
# 创建 QSettings 对象,参数为 组织名 和 应用名[reference:65]
settings = QSettings("MyCompany", "MyApp")
# 保存设置
settings.setValue("mainwindow/geometry", self.saveGeometry())
settings.setValue("mainwindow/state", self.saveState())
# 加载设置
geometry = settings.value("mainwindow/geometry")
if geometry:
self.restoreGeometry(geometry)
---------------------------------------------------------------------------------------------------------------------------------
注意事项
信号与槽的参数类型:信号发射的参数个数可以多于槽函数接收的参数,但反之不行。多余的参数会被忽略。
多线程安全:再次强调,绝对不要在子线程中直接操作 GUI 控件,这是导致程序崩溃或出现不可预知错误的常见原因。
QThread的生命周期:确保QThread对象不会被过早销毁。通常将其设为所在窗口的子对象,或将其引用保存为实例变量(如self.thread)。QTimer的精度:QTimer的精度依赖于底层操作系统和系统负载,不适用于需要高精度计时的场景(如音乐节拍器)。对于高精度计时,应使用QElapsedTimer。QFile的编码:QFile默认以二进制模式操作。读写文本文件时,建议使用QTextStream并指定编码(如stream.setCodec("UTF-8"))以避免乱码。QSettings的存储位置:QSettings的存储位置是平台相关的。你无需关心具体存储在哪里,只需通过统一的 API 读写即可。