PYQT5连接数据库
Model和View分离的设计模式,最直接的应用就是操作数据库,这里使用MySQL的数据库,Qt提供了一系列的组件可以帮助我们直接连接和操作数据库,但是针对MySQL,这里面有个大坑啊。
先来安装MySQL,安装MySQL的方法可以看这个MySQL安装配置
然后需要找到一些数据用来使用,Github上有一个项目提供了各种数据库的数据源,链接是这个chinook
最后如果使用的是VScode,可以下载一个插件来查看数据库,链接是这个MySQL
准备工作完事了,把数据库的操作放到一个Class里面
如果安装的PYQT是最新的,那么执行后多半弹出来的是这个
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QODBC QODBC3 QPSQL QPSQL7
connection failed
就是告诉你,驱动不能加载,可用的驱动就是列出来的那几个,但是根本没有QMYSQL,说到底就是最新的PYQT压根没这个驱动,那咋办呢,网上找一个呗,你可以试试,找死你,不过我找到了,链接是这个
QMYSQL驱动
打开后是这样的页面
把这个四个都下载了,我用的是第三个,然后解压,里面有个release的文件夹,然后有个文件名字叫qsqlmysql.dll,把这个拷贝到这里
C:\Users\用户名\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\PyQt5\Qt\plugins\sqldrivers
之后把libmysql.dll这个文件拷贝到这里
C:\Users\用户名\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\PyQt5\Qt\bin
然后在执行一下你试试,要不Ok,你就试下另外几个文件,都是release里面这个名字qsqlmysql.dll的文件
然后写窗口程序
这段代码执行后,数据就出来了
数据查询
数据库的查询需要用到一个QSqlQuery的类
功能是要要实现在输入框内输入不同的字段,数据表按照输入的字段筛选出正确的查询结果。是这样的
需要用到QSqlQuery的两个方法,一个是QSqlQuery.prepare,另外一个是QSqlQuery.bindValue
看名字就知道一个是准备查询的语句,一个是把查询语句中的变量和外部值绑定
使用的是Chinook的invoice表,通过在输入框输入用户Id实时筛选结果,界面是通过QDesigner拖拽的,通过pyuic5命令转成python格式,之后调用
首先需要构造出一个SQL语句用于查询需要的内容,有关SQL相关的内容可以网上找
这里的Model需要使用QSqlQueryModel类,这个类是针对数据库查询的一个专门的Model,可以将数据与View关联
查询语句里面需要使用bindValue方法连接数据,需要写成
(:VARIABLE_1, :VARIABLE_2......)
的形式,通过bindValue方法可以通过名称和位置两种方式进行复制,具体见例子
update_query方法里面使用bindValue将CustomerID和查询语句里面的字段绑定,之后使用QSqlQueryModel的setQuery方法获取Model数据吗,之后就是最前面的那个GIF图片了
如果要查询一段时间的数据,首先需要构造一下查询语句,应该是这样
SELECT * FROM `chinook`.`invoice` LIMIT 1000;
SELECT `invoice`.`CustomerId`,
`invoice`.`InvoiceDate`,
`invoice`.`BillingAddress`
FROM `chinook`.`invoice`
WHERE `invoice`.`CustomerId` = 23 AND `InvoiceDate` <= 某个时间('2013-1-1 00:00:00')
某个时间可以使用日期时间控件获得,使用日期时间控件的dateTimeChanged触发函数update_query
self.startTime.dateTimeChanged.connect(self.update_query)
使用bindValue绑定下数据
self.query.bindValue(":dataTime", dateTime)
最终的代码是这样的
当改变时间的时候,查询的结果随之变化
数据Map到控件
有些时候需要将数据进行这样的关联以方便修改
这个时候需要使用到一个QDataWidgetMapper的类,可以将数据表中的每一列关联到不同的控件
这里使用Chinook中Track表来举例,这个表中不同的字段使用不同的控件来对数据进行修改,如下表
字段名 | 控件名称 | 读写 |
---|---|---|
TrackId | QSpinBox | 不可 |
Name | QLineEdit | 可以 |
Composer | QLineEdit | 可以 |
Album | QComboBox | 可以 |
MediaType | QComboBox | 可以 |
Genre | QComboBox | 可以 |
Milliseconds | QSpinBox | 可以 |
Bytes | QSpinBox | 可以 |
Price | QSpinBox | 可以 |
按照这个表设计界面是这个样子
Track表有三个关联表,分别对应表中的三个字段,分别是AlbumId,MediaTypeId,GenreId,为了让QComboBox能正确显示数据,需要使用一个新的Model类QSqlRelationalTableModel,这个类处理关联型的表数据,通过setRelation方法给定一个QSqlRelation类作为参数,QSqlRelation有三个参数,分别是与Track关联的表名,Track表中的关联字段也就是foreign key,关联表中的字段名,下图说明这一点
左边是Main Table,右边是Relation Table,Relation Table的表名就是第一个参数,Main Table中的typeindex字段名是第二个参数,Relation Table中的description字段名就是第三个参数
接下需要将三个关联型的字段(AlbumId,MediaTypeId,GenreId)分别与QComboBox控件关联起来,需要用到一个relationModel方法,传入的参数就是Track表中的Foreign Key对应的Column
接下来需要使用到QDataWidgetMapper把Model映射到控件,一个Map实例可以实现所有控件的映射
这样就完成了
接下来可以通过按钮来控制数据的切换和保存,Previous和Next按钮是控制显示下一条和上一条数据,Save Change是保存修改
效果是这个样子的
底下是完整的代码图片