版权声明
无需授权即可转载

PYQT5连接数据库

Model和View分离的设计模式,最直接的应用就是操作数据库,这里使用MySQL的数据库,Qt提供了一系列的组件可以帮助我们直接连接和操作数据库,但是针对MySQL,这里面有个大坑啊。
先来安装MySQL,安装MySQL的方法可以看这个MySQL安装配置
然后需要找到一些数据用来使用,Github上有一个项目提供了各种数据库的数据源,链接是这个chinook
最后如果使用的是VScode,可以下载一个插件来查看数据库,链接是这个MySQL
准备工作完事了,把数据库的操作放到一个Class里面
image.png
如果安装的PYQT是最新的,那么执行后多半弹出来的是这个

  1. QSqlDatabase: QMYSQL driver not loaded
  2. QSqlDatabase: available drivers: QSQLITE QODBC QODBC3 QPSQL QPSQL7
  3. connection failed

就是告诉你,驱动不能加载,可用的驱动就是列出来的那几个,但是根本没有QMYSQL,说到底就是最新的PYQT压根没这个驱动,那咋办呢,网上找一个呗,你可以试试,找死你,不过我找到了,链接是这个
QMYSQL驱动
打开后是这样的页面
image.png
把这个四个都下载了,我用的是第三个,然后解压,里面有个release的文件夹,然后有个文件名字叫qsqlmysql.dll,把这个拷贝到这里

  1. C:\Users\用户名\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\PyQt5\Qt\plugins\sqldrivers

之后把libmysql.dll这个文件拷贝到这里

  1. C:\Users\用户名\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\PyQt5\Qt\bin

然后在执行一下你试试,要不Ok,你就试下另外几个文件,都是release里面这个名字qsqlmysql.dll的文件

然后写窗口程序
image.png

这段代码执行后,数据就出来了
image.png

数据查询

数据库的查询需要用到一个QSqlQuery的类
功能是要要实现在输入框内输入不同的字段,数据表按照输入的字段筛选出正确的查询结果。是这样的
006.gif
需要用到QSqlQuery的两个方法,一个是QSqlQuery.prepare,另外一个是QSqlQuery.bindValue
看名字就知道一个是准备查询的语句,一个是把查询语句中的变量和外部值绑定
使用的是Chinook的invoice表,通过在输入框输入用户Id实时筛选结果,界面是通过QDesigner拖拽的,通过pyuic5命令转成python格式,之后调用
image.png
首先需要构造出一个SQL语句用于查询需要的内容,有关SQL相关的内容可以网上找
这里的Model需要使用QSqlQueryModel类,这个类是针对数据库查询的一个专门的Model,可以将数据与View关联
image.png
查询语句里面需要使用bindValue方法连接数据,需要写成

  1. (:VARIABLE_1, :VARIABLE_2......)

的形式,通过bindValue方法可以通过名称和位置两种方式进行复制,具体见例子
image.png
update_query方法里面使用bindValue将CustomerID和查询语句里面的字段绑定,之后使用QSqlQueryModel的setQuery方法获取Model数据吗,之后就是最前面的那个GIF图片了
如果要查询一段时间的数据,首先需要构造一下查询语句,应该是这样

  1. SELECT * FROM `chinook`.`invoice` LIMIT 1000;
  2. SELECT `invoice`.`CustomerId`,
  3. `invoice`.`InvoiceDate`,
  4. `invoice`.`BillingAddress`
  5. FROM `chinook`.`invoice`
  6. WHERE `invoice`.`CustomerId` = 23 AND `InvoiceDate` <= 某个时间('2013-1-1 00:00:00')

某个时间可以使用日期时间控件获得,使用日期时间控件的dateTimeChanged触发函数update_query

  1. self.startTime.dateTimeChanged.connect(self.update_query)

使用bindValue绑定下数据

  1. self.query.bindValue(":dataTime", dateTime)

最终的代码是这样的
image.png
当改变时间的时候,查询的结果随之变化
007.gif

数据Map到控件

有些时候需要将数据进行这样的关联以方便修改
说人话的PYQT5『4』 - 图11
这个时候需要使用到一个QDataWidgetMapper的类,可以将数据表中的每一列关联到不同的控件
这里使用Chinook中Track表来举例,这个表中不同的字段使用不同的控件来对数据进行修改,如下表

字段名 控件名称 读写
TrackId QSpinBox 不可
Name QLineEdit 可以
Composer QLineEdit 可以
Album QComboBox 可以
MediaType QComboBox 可以
Genre QComboBox 可以
Milliseconds QSpinBox 可以
Bytes QSpinBox 可以
Price QSpinBox 可以

按照这个表设计界面是这个样子
image.png
Track表有三个关联表,分别对应表中的三个字段,分别是AlbumId,MediaTypeId,GenreId,为了让QComboBox能正确显示数据,需要使用一个新的Model类QSqlRelationalTableModel,这个类处理关联型的表数据,通过setRelation方法给定一个QSqlRelation类作为参数,QSqlRelation有三个参数,分别是与Track关联的表名,Track表中的关联字段也就是foreign key,关联表中的字段名,下图说明这一点
说人话的PYQT5『4』 - 图13
左边是Main Table,右边是Relation Table,Relation Table的表名就是第一个参数,Main Table中的typeindex字段名是第二个参数,Relation Table中的description字段名就是第三个参数
image.png
接下需要将三个关联型的字段(AlbumId,MediaTypeId,GenreId)分别与QComboBox控件关联起来,需要用到一个relationModel方法,传入的参数就是Track表中的Foreign Key对应的Column
image.png
接下来需要使用到QDataWidgetMapper把Model映射到控件,一个Map实例可以实现所有控件的映射
image.png
这样就完成了
008.gif
接下来可以通过按钮来控制数据的切换和保存,Previous和Next按钮是控制显示下一条和上一条数据,Save Change是保存修改
image.png
效果是这个样子的
009.gif
底下是完整的代码图片
image.png