本文全面解析PyQt中SQLite数据库操作,从基础连接到高级模型视图,最后封装实用的分页查询控件
在桌面应用开发中,数据库操作是不可或缺的核心功能。PyQt作为强大的Python GUI框架,提供了完善的数据库支持。本文将手把手教你使用PyQt操作SQLite数据库,并实现一个企业级的分页查询控件。
一、SQLite简介与安装配置
1.1 SQLite核心优势
SQLite是轻量级嵌入式数据库引擎,具备以下独特优势:
- 零配置部署:无需服务器,单文件存储
- 事务支持:ACID兼容,保证数据一致性
- 跨平台:支持所有主流操作系统
- 高性能:在多数场景下优于客户端/服务器数据库
1.2 安装与配置
-
从官网下载预编译二进制文件:
https://www.sqlite.org/download.html -
配置环境变量(Windows示例):
D:\Program Files\sqlite-tools-win-x64-3500100\sqlite3 -
验证安装:
sqlite3 --version
二、PyQt数据库连接与操作
2.1 数据库连接
PyQt通过QSqlDatabase类管理数据库连接:
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('./db/database.db')
if not db.open():
QMessageBox.critical(None, "数据库错误",
"无法建立数据库连接,请检查配置")
return False
关键点:
- 使用
addDatabase()指定驱动类型 - SQLite驱动名为
'QSQLITE' - 必须显式调用
open()建立连接 - 使用后务必
close()释放资源
2.2 执行SQL语句
使用QSqlQuery执行DDL和DML操作:
query = QSqlQuery()
创建表
query.exec_("CREATE TABLE people("
"id INT PRIMARY KEY,"
"name VARCHAR(20),"
"address VARCHAR(30))")
插入数据
query.exec_("INSERT INTO people VALUES(1, '张三', '北京')")
注意事项:
- 使用
exec_()而非exec()(PyQt5特殊命名) - 错误处理:检查
lastError().isValid() - 批量操作使用事务提升性能
2.3 窗口中的数据库生命周期管理
在窗口中使用数据库时,需要合理管理连接生命周期:
class DatabaseWindow(QWidget):
def __init__(self):
self.db = QSqlDatabase.addDatabase('QSQLITE')
self.db.setDatabaseName('app.db')
self.db.open() # 窗口初始化时打开
def closeEvent(self, event):
self.db.close() # 窗口关闭时断开
event.accept()
三、高级模型/视图操作
3.1 QSqlTableModel的使用
QSqlTableModel提供高级接口操作单表数据:
model = QSqlTableModel()
model.setTable("people")
model.setEditStrategy(QSqlTableModel.OnManualSubmit)
model.setFilter("id > 1")
model.select()
设置表头
model.setHeaderData(0, Qt.Horizontal, "ID")
model.setHeaderData(1, Qt.Horizontal, "姓名")
3.2 编辑策略详解
| 策略类型 | 描述 | 适用场景 |
|---|---|---|
| OnFieldChange | 即时提交修改 | 需要实时保存 |
| OnRowChange | 行变更时提交 | 表单编辑 |
| OnManualSubmit | 手动提交 | 批量操作 |
在视图中显示数据
view = QTableView()
view.setModel(model)
view.show()

3.3 增删改查实现
添加记录
def add_row():
model.insertRow(model.rowCount())
删除当前行
def delete_row():
model.removeRow(view.currentIndex().row())
提交修改
def submit_changes():
model.submitAll()
四、封装分页查询控件
4.1 分页控件设计思路
实现功能完备的分页控件需要:
- 计算总页数:
总记录数/每页大小 - 实现分页查询:SQL的
LIMIT offset, count - 设计直观的UI界面
- 处理边界情况(首页/末页)
4.2 核心实现代码
class DataGrid(QWidget):
def __init__(self):
self.PageRecordCount = 10 # 每页记录数
self.currentPage = 1 # 当前页码
self.totalPage = 0 # 总页数
self.totalRecordCount = 0 # 总记录数
def recordQuery(self, limitIndex):
"""执行分页查询"""
query = f"SELECT * FROM student LIMIT {limitIndex}, {self.PageRecordCount}"
self.queryModel.setQuery(query)
def getPageCount(self):
"""计算总页数"""
if self.totalRecordCount % self.PageRecordCount == 0:
return self.totalRecordCount // self.PageRecordCount
else:
return self.totalRecordCount // self.PageRecordCount + 1
4.3 分页导航实现
def createWindow(self):
# 分页控件布局
operatorLayout = QHBoxLayout()
self.prevButton = QPushButton("前一页")
self.nextButton = QPushButton("后一页")
self.switchPageButton = QPushButton("跳转")
self.switchPageLineEdit = QLineEdit()
operatorLayout.addWidget(self.prevButton)
operatorLayout.addWidget(self.nextButton)
operatorLayout.addWidget(QLabel("转到第"))
operatorLayout.addWidget(self.switchPageLineEdit)
operatorLayout.addWidget(QLabel("页"))
operatorLayout.addWidget(self.switchPageButton)
# 信号连接
self.prevButton.clicked.connect(self.onPrevButtonClick)
self.nextButton.clicked.connect(self.onNextButtonClick)
self.switchPageButton.clicked.connect(self.onSwitchPageButtonClick)
4.4 页码跳转逻辑
def onSwitchPageButtonClick(self):
pageIndex = int(self.switchPageLineEdit.text())
# 验证页码有效性
if pageIndex < 1 or pageIndex > self.totalPage:
QMessageBox.warning(self, "输入错误", "无效的页码")
return
# 计算查询偏移量
limitIndex = (pageIndex - 1) * self.PageRecordCount
self.recordQuery(limitIndex)
self.currentPage = pageIndex
self.updateStatus()

五、最佳实践与性能优化
5.1 数据库操作黄金法则
- 连接管理:用时打开,用完关闭
- 错误处理:检查所有数据库操作的返回值
- 事务使用:批量操作时显式使用事务
db.transaction() try: # 批量操作 db.commit() except: db.rollback() - 参数化查询:防止SQL注入
query.prepare("INSERT INTO people VALUES (?, ?, ?)") query.addBindValue(id) query.addBindValue(name) query.addBindValue(address) query.exec_()
5.2 高级技巧
- 视图代理:自定义数据显示格式
class DateDelegate(QStyledItemDelegate): def displayText(self, value, locale): return QDateTime.fromString(value, Qt.ISODate).toString("yyyy-MM-dd") - 数据库连接池:高并发场景优化
- 异步查询:防止UI卡顿
- ORM整合:使用SQLAlchemy等ORM框架
结语
通过本文的学习,你已经掌握了:
- PyQt中SQLite数据库的基本操作
- 模型/视图框架的高级应用
- 分页查询控件的设计与实现
- 数据库编程的最佳实践
数据库是应用的核心,良好的数据库设计和管理能力,是高级GUI开发者的必备技能。本文的封装思路不仅适用于SQLite,稍作修改即可支持MySQL、PostgreSQL等数据库。
技术更新日新月异,但基础原理永恒不变。扎实掌握核心概念,方能以不变应万变。
974

被折叠的 条评论
为什么被折叠?



