152-数据库操作和模型-QSQL模型简介以及 查询模型QSqlQueryModel

QSQL模型

除了 QSqlQuery,Qt中还提供了3个用于访问数据库的更高级别的类,分别为QSq1QueryModel、QSqlTableModel 和 QSqlRelationalTableModel。这3个类的结构关系如图所示,作用如表所示。

用SQL命令对数据库进行操作并不直观,PySide 提供了对数据库进行可视化操作的Model/View 结构,通过数据库模型读入在数据库中查询到的数据,并通过视图控件(如QTableView)显示数据库模型中的数据,通过代理控件在视图控件中对数据进行新增更新、删除等操作,再通过数据模型把操作后的数据保存到数据库中。

PySide 提供的数据库模型有 QSqlQueryModel、QSqlTableModel和 QSqlRelationalTableModel,它们之间的继承关系如图所示。

image-20230326002633368

描 述
QSqlQueryModel基于任意 SQL查询的只读模型
QSqITableModel适用于单个表的读/写模型
QSqIRelationaITableModel具有外键支持的QSqlTableModel 子类

查询模型QSqlQueryModel

QSqlQueryModel类为SQL结果集提供只读数据模型

数据库查询模型 QSlQueryModel 只能从数据库中读取数据,而不能修改数据,可以用视图控件,例如 QTableView 来显示查询模型 QSqlQueryModel 中的数据。

用QSglQueryModel 创建数据库查询模型对象的方法如下所示。

from PySide6.QtSql import QSqlQueryModel

QSqlQueryModel(parent: Union[PySide6.QtCore.QObject,NoneType] = None)-> None 
查询模型QSqlQueryModel官方说明

QSqlQueryModel是一个高级接口,用于执行SQL语句和遍历结果集。它构建在较低级别的QSqlQuery之上,可用于为视图类(如QTableView)提供数据。例如:

model = QSqlQueryModel()
model.setQuery("SELECT name, salary FROM employee")
model.setHeaderData(0, Qt.Horizontal, tr("Name"))
model.setHeaderData(1, Qt.Horizontal, tr("Salary"))

view = QTableView()

view.setModel(model)

view.show()

我们设置了模型的查询,然后设置了视图标题中显示的标签。
QSqlQueryModel也可以用于以编程方式访问数据库,而无需将其绑定到视图:

model = QSqlQueryModel()
model.setQuery("SELECT name, salary FROM employee")
salary = model.record(4).value("salary").toInt()

上面的代码片段从SELECT查询的结果集中的记录4中提取了salary字段。由于工资是第二列(或列索引1),我们可以将最后一行重写如下:

salary = model.data(model.index(4, 1)).toInt()

默认情况下,该模型是只读的。要使其读写,必须对其进行子类化并重新实现setData()和flags()。另一种选择是使用QSqlTableModel,它提供了一个基于单个数据库表的读写模型。
querymodel示例说明了如何使用QSqlQueryModel来显示查询的结果。它还展示了如何在向用户显示数据之前对QSqlQueryModel进行子类化以自定义数据的内容,以及如何基于QSqlQueryModel创建读写模型。
如果数据库没有返回查询中所选行的数量,则模型将递增地获取行。有关详细信息,请参阅fetchMore()。

查询模型 QSqlQueryModel 的常用方法

数据库查询模型 QSqlQueryModel的常用方法如表所示主要方法

  • 用setQuery(query:QSqlQuery)方法或 setQuery(query:str,db;QSqlDatabase = Default(QSqlDatabase))方法设置数据库查询 QSqlQuery;
  • 用setHeaderData(section: int,orientation:Qt.Orientation,value: Any,role: int=Qt.EditRole)方法设置显示数据的视图控件表头某角色的值
    • 在 orientation 取 Qt.Horizontal,并且 section 取值合适时返回True,其他情况返回 False
    • 其中 value 是某种角色的值,section 是列索引
QSqlQueryModel的方法及参数类型返回值的类型说明
setQuery(query:QSqlQuery)None设置数据库查询
setQuery(query:str,db: QSqlDatabase= Default(QSqlDatabase))None设置数据库查询
query()QSqlQuery获取数据查询
setHeaderData(section:int,orientation: Qt.Orientation,value: Any,role: int = Qt.EditRole)bo01设置显示数据的视图控件(如 QTableView)表头某角色的值
headerData(section: int,orientation: Qt.Orientation,role: int = Qt.ItemDataRole. DisplayRole)Any获取显示数据的视图控件表头某种角 色的值
record()QSqlRecord获取包含字段信息的空记录
record(row:int)QSqlRecord获取指定的字段记录
rowCount(parent: QModelIndex= Invalid(QModelIndex))int获取数据表中记录(行)的数量
columnCount(parent:QModelIndex=Invalid(QModelIndex))int获取数据表中字段(列)的数量
clear()None清空查询模型中的数据
查询模型QSqlQueryModel的应用实例

下面的程序用菜单打开前一节创建的 SQLite数据库文件 student score_new.db

用QTableView 控件显示出数据表中的数据用QComboBox控件显示数据库中的数据表名称在QComboBox中选择不同的数据表名称时QTableView 控件将同步显示该数据表中的数据

# -*- coding: UTF-8 -*-
# File date: Hi_2023/3/12 23:23
# File_name: 03-数据库查询模型QSqlQueryModel的应用实例.py

from PySide6.QtWidgets import QApplication,QWidget,QComboBox,QTableView,QLabel,QHBoxLayout,QVBoxLayout,QFileDialog,QMenuBar
from PySide6.QtSql import QSqlDatabase,QSqlQueryModel
from PySide6.QtCore import Qt
import sys


class MyWidget(QWidget):
    def __init__(self,parent=None):
        super().__init__(parent)

        self.setupUi()

    def setupUi(self):
        menuBar = QMenuBar()
        fileMenu = menuBar.addMenu("文件(&F)")

        fileMenu.addAction("打开(&0)").triggered.connect(self.actionOpen)
        fileMenu.addSeparator()
        fileMenu.addAction("关闭(&E)").triggered.connect(self.close)

        label = QLabel("选择数据表:")
        self.combox = QComboBox()
        self.combox.currentTextChanged.connect(self.comboxTextChanged)
        H = QHBoxLayout()
        H.addWidget(label,stretch=0)
        H.addWidget(self.combox,stretch=1)

        self.tableView = QTableView()
        self.tableView.setAlternatingRowColors(True)
        V = QVBoxLayout(self)
        V.addWidget(menuBar)
        V.addLayout(H)
        V.addWidget(self.tableView)

    def actionOpen(self):
        dbFile,fil = QFileDialog.getOpenFileName(self,dir=".",filter="SQLite(*.db *.db3)")
        if dbFile:
            self.setWindowTitle(dbFile)
            self.combox.clear()
            self.db = QSqlDatabase.addDatabase("QSQLITE")
            self.db.setDatabaseName(dbFile)
            self.sqlQueryModel = QSqlQueryModel(self)
            if self.db.open():  # 数据库查询模型
                tables = self.db.tables()
                if len(tables)> 0:
                    self.combox.addItems(tables)

    def comboxTextChanged(self,text):
        self.sqlQueryModel.setQuery("SELECT * FROM {}".format(text),self.db)

        header = self.sqlQueryModel.record()
        for i in range(header.count()):
            self.sqlQueryModel.setHeaderData(i,Qt.Orientation.Horizontal,header.fieldName(i),Qt.DisplayRole)
        self.tableView.setModel(self.sqlQueryModel)# 设置表格视图的数据模型


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MyWidget()

    win.show()
    sys.exit(app.exec())

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值