4.2 与表格关联的模型
如果要编辑数据库中的数据,城使用QSqlTableModel类。 QSqlTableModel类的继承层次如下:
QObject - QAbstractltemModel - QAbstractTableModel - QSqlQueryModel - QSqlTableModel
QSqlTableModel类的构造函数为:
QSqlTableModel([QObject parent = Q_NULLPTR][, QSqlDatabase db = QSqlDatabase()]):创建一个父类为parent的QSqlTableModel实例,并将数据库连接设置为db。 如果db无效,将使用默认的数据库连接。
QSqlTableModel类继承了QSqlQueryModel类中的所有方法,除此之外,还定义了以下方法(详见http://doc.qt.io/qt-5/qsqltablemodel.html):
setTable(QString tableName): 设置呈现在模型中的数据库中的tableName表。该方法只是读取表结构信息,并不包括数据。
tableName():呈现在模型中的数据库表名。
setSort(int column, Qt.SortOrder order): 设置数据按column进行order方式排序。
setFilter( QString filter):设置过滤器为filter.过滤器是一个没有关键字WHERE的SQL WHERE子句,例如:name='Josephine'
filter():返回过滤器。
select(): 根据排序方式、过滤器,将数据填充到表格中。
setEditStrategy(EditStrategy strategy):设置编辑策略。EditStrategy枚举变量有下列值:
OnFieldChange:模型的所有更改将立即作用于数据库。
OnRowChange:当切换到其他行时,模型的更改作用于数据库。
OnManualSubmit:模型中的理改先缓存,仅调用submitAll()或 revertAll()后,才作用于数据库。
insertRow(int row[, QModelIndex parent= QModelIndex()]): 在row条记录前增加一条。
insertRows(int row,int count,[, QModelIndex parent= QModelIndex()]): 在row条记录前增加count条记录。
setData(QModelIndex index, const QVariant value, int role = Qt.EditRole):设置index索引的值为value.
removeRow(int row[, QModelIndex parent = QModelIndex()]):删除第row条记录。
removeRows(int row,int count[, QModelIndex parent = QModelIndex()]):删除第row条开始的count条记录。
注意:
通过调用removeRow( )或removeRows( )方法删除条目后,将在模型中留下空记录,但并不代表数据库表中的任何记录,所以需要调用selec()方法重新读取模型中的数据来删除model中的空记录。
insertRecord(int row, QSqlRecord record):在row位置插入记录record.如果,row为-1,表示在末尾插入。
setRecord(int row, QSqlRecord values):将模型中row行的内容用values取代。 源和目标字段是按字段名称映射,而不是按记录中的位置。
submit(): 如果设置了OnManualSubmit编辑模式,则将当前记录中所做的更改作用于数据库。
submitAll(): 如果设置了OnManualSubmit编辑模式,则将模型中所有修改的记录作用于数据库。
revert():如果设置了OnManualSubmit编辑模式,则取消当前记录中所做的更改。
revertRow(int row):如果设置了OnManualSubmit编辑模式,则取消对row条记录所做的更改。
revertAll():如果设置了OnManualSubmit编辑模式,则取消对所有记录所做的更改。
selectRow(int row):使用数据库表row行的值刷新模型中的对应行。
isDirty([QModelIndex index]):如果模型index中有尚未提交到数据库的修改值,则返回True,否则返回False。
fieldIndex(QString fieldName): 返回fieldName字段的索引;
primaryKey():返回代表主键的一个QSqlIndex实例。
insertRecord()和setRecord()的第二个参数为QSqlRecord实例,QSqlRecord类的构造函数为:
QSqlRecord(QSqlRecord other)
如果带参数,则是创建other的副本。通常是通过调用QSqlDatabase类的record()返回一个 QSqlRecord实例。当编辑已有记录时,则是调用QSqlTableModel类的record(),返回一个代表当前记录的QSqlRecord实例。
QSqlRecord类除了“PyQt5编程(37)”中提到的方法外,还有以下方法:
value(int index):返回当前记录的index字段的值。
value(Qstring fieldname):返回当前记录的fieldname字段的值。
setValue(int index, QVariant val):将当前记录的index字段的值设置为val。
setValue(QString name, const QVariant val):将当前记录的fieldname字段的值设置为val。
isNull(int index): 如果当前记录中index字段值为空值,返回True;否则返回False。
isNull(QString name):如果当前记录中name字段值为空值,返回True;否则返回False。
setNull(int index): 设置当前记录中index字段值为空值。
setNull(QString name):设置当前记录中name字段值为空值。
clearValues():清除记录中所有字段的值,并将每个字段设置为空。
setGenerated(int index, bool generated):将index字段的生成标志(generated flag)置位。
setGenerated(QString name, bool generated):将name字段的生成标志(generated flag)置位。
isGenerated(int index, bool generated):返回index字段的生成标志(generated flag)。
isGenerated(QString name, bool generated):返回name字段的生成标志(generated flag)。
添加记录到模型的示例代码:
con = QtSql.QSqlDatabase.addDatabase ('QSQLITE')
con.setDatabaseName ('data.sqlite')
con.open ()
stm = QtSql.QSqlTableModel ()
stm.setTable ('good')
stm.select ()
rec = con.record ('good')
rec.setValue ('goodname', 'Mouse pad')
rec.setValue ('goodcount', 3)
stm.insertRecord (-1, rec)
修改现有记录3的示例代码:
rec = stm.record(3)
rec.setValue('goodcount', 5)
stm.setRecord(3, rec)
QSqlTableModel类有以下信号:
primeInsert(int row, QSqlRecord record):在当前活动数据库表的给定行中时,insertRows()触发。
beforeInsert(QSqlRecord record):在当前活动数据库表中插入数据时,由insertRowIntoTable()触发。
beforeUpdate(int row, QSqlRecord record):在row行记录更新前,由updateRowInTable()触发。
beforeDelete(int row):在删除row行数据之前,由deleteRowFromTable()触发。
dataChanged(QModelIndex topLeft, QModelIndex bottomRight[, QVector roles = QVector ()]): 模型中的数据变化时触发。如果受影响的数据属同一父类,其区域为topleft到bottomright。可选的roles参数用于指定哪些数据实际上已被修改, 该参数为空, 意味着所有数据都已修改。
如果模型为OnManualSubmit编辑模式,那么dataChanged信号是调用submit()或submitAll()方法的理想场所。下列为数据库操作的相关代码,它不仅可以编辑,还可以通过按下相应的按钮来添加和删除记录。
from PyQt5 import QtCore, QtWidgets, QtSql
import sys
def addRecord ():
# 插入空记录,用户可手动输入
stm.insertRow (stm.rowCount ())
def delRecord ():
# 从模型中删除记录
stm.removeRow (tv.currentIndex (). row ())
# 重新加载数据到模型中
stm.select ()
app = QtWidgets.QApplication (sys.argv)
window = QtWidgets.QWidget ()
window.setWindowTitle ("QSqlTableModel")
Establish a connection to the database
con = QtSql.QSqlDatabase.addDatabase ('QSQLITE')
con.setDatabaseName ('data.sqlite')
con.open ()
Create a model
stm = QtSql.QSqlTableModel (parent = window)
stm.setTable ('good')
stm.setSort (1, QtCore.Qt.AscendingOrder)
stm.select ()
Set the headers for the columns of the model
stm.setHeaderData (1, QtCore.Qt.Horizontal, 'Name')
stm.setHeaderData (2, QtCore.Qt.Horizontal, 'Qty')
Set the table just created for the table
vbox = QtWidgets.QVBoxLayout ()
tv = QtWidgets.QTableView ()
tv.setModel (stm)
隐藏第一列
tv.hideColumn (0)
tv.setColumnWidth (1, 150)
tv.setColumnWidth (2, 60)
vbox.addWidget (tv)
btnAdd = QtWidgets.QPushButton ("添加记录(&A)")
btnAdd.clicked.connect (addRecord)
vbox.addWidget (btnAdd)
btnDel = QtWidgets.QPushButton ("删除记录(&A")
btnDel.clicked.connect (delRecord)
vbox.addWidget (btnDel)
window.setLayout (vbox)
window.resize (300, 250)
window.show ()
sys.exit (app.exec_ ())
<wbr> <wbr> 4.2 与表格关联的模型
<wbr> <wbr> 如果要编辑数据库中的数据,城使用QSqlTableModel类。 <wbr>QSqlTableModel类的
继承层次如下: <wbr>
<font face="Microsoft YaHei, Helvetica Neue, SimSun" color="#494949"> <wbr> <wbr> <wbr></font>QObject - QAbstractltemModel - QAbstractTableModel - QSqlQueryModel - QSqlTableModel
<wbr> <wbr> QSqlTableModel类的构造函数为:
<wbr> <wbr> QSqlTableModel([QObject parent = Q_NULLPTR][, QSqlDatabase db = QSqlDatabase()]):创建一个父类为parent的QSqlTableModel实例,并将数据库连接设置为db。 如果db无效,将使用默认的数据库连接。
<wbr> <wbr> <wbr>QSqlTableModel类继承了QSqlQueryModel类中的所有方法,除此之外,还定义了以下方法(详见http://doc.qt.io/qt-5/qsqltablemodel.html):
- setTable(QString tableName): 设置呈现在模型中的数据库中的tableName表。该方法只是读取表结构信息,并不包括数据。
- tableName():呈现在模型中的数据库表名。
- setSort(int column, Qt.SortOrder order): 设置数据按column进行order方式排序。
- setFilter( <wbr>QString filter):设置过滤器为filter.过滤器是一个没有关键字WHERE的SQL WHERE子句,例如:name='Josephine'
- filter():返回过滤器。
- select(): 根据排序方式、过滤器,将数据填充到表格中。
- setEditStrategy(EditStrategy strategy):设置编辑策略。EditStrategy枚举变量有下列值:
- OnFieldChange:模型的所有更改将立即作用于数据库。
- OnRowChange:当切换到其他行时,模型的更改作用于数据库。
- OnManualSubmit:模型中的理改先缓存,仅调用submitAll()或 revertAll()后,才作用于数据库。
- insertRow(int row[, QModelIndex <wbr>parent= QModelIndex()]): 在row条记录前增加一条。
- insertRows(int row,int count,[, QModelIndex <wbr>parent= QModelIndex()]): 在row条记录前增加count条记录。
- setData(QModelIndex index, const QVariant value, int role = Qt.EditRole):设置index索引的值为value.
- removeRow(int row[, QModelIndex parent = QModelIndex()]):删除第row条记录。
- removeRows(int row,int count[, QModelIndex parent = QModelIndex()]):删除第row条开始的count条记录。
<font color="#FF0000"> <wbr> <wbr> <wbr>注意:</font>
<wbr> <wbr> 通过调用removeRow( )或removeRows( )方法删除条目后,将在模型中留下空记录,但并不代表数据库表中的任何记录,所以需要调用selec()方法重新读取模型中的数据来删除model中的空记录。
- insertRecord(int row, QSqlRecord record):在row位置插入记录record.如果,row为-1,表示在末尾插入。
- setRecord(int row, QSqlRecord values):将模型中row行的内容用values取代。 源和目标字段是按字段名称映射,而不是按记录中的位置。
- submit(): <wbr>如果设置了OnManualSubmit编辑模式,则将当前记录中所做的更改作用于数据库。 <wbr>
- submitAll(): <wbr>如果设置了OnManualSubmit编辑模式,则将模型中所有修改的记录作用于数据库。 <wbr>
- revert():如果设置了OnManualSubmit编辑模式,则取消当前记录中所做的更改。
- revertRow(int row):如果设置了OnManualSubmit编辑模式,则取消对row条记录所做的更改。
- revertAll():如果设置了OnManualSubmit编辑模式,则取消对所有记录所做的更改。
- selectRow(int row):使用数据库表row行的值刷新模型中的对应行。
- isDirty([QModelIndex index]):如果模型index中有尚未提交到数据库的修改值,则返回True,否则返回False。
- fieldIndex(QString fieldName): 返回fieldName字段的索引;
- primaryKey():返回代表主键的一个QSqlIndex实例。
<wbr> <wbr> insertRecord()和setRecord()的第二个参数为QSqlRecord实例,QSqlRecord类的构造函数为:
<wbr> <wbr> <wbr>QSqlRecord(QSqlRecord other)
<wbr> <wbr> <wbr>如果带参数,则是创建other的副本。通常是通过调用QSqlDatabase类的record()返回一个 QSqlRecord实例。当编辑已有记录时,则是调用QSqlTableModel类的record(),返回一个代表当前记录的QSqlRecord实例。
<wbr> <wbr> QSqlRecord类除了“PyQt5编程(37)”中提到的方法外,还有以下方法:
- value(int index):返回当前记录的index字段的值。
- value(Qstring fieldname):返回当前记录的fieldname字段的值。
- setValue(int index, QVariant val):将当前记录的index字段的值设置为val。
- setValue(QString name, const QVariant val):将当前记录的fieldname字段的值设置为val。
- isNull(int index): 如果当前记录中index字段值为空值,返回True;否则返回False。
- isNull(QString name):如果当前记录中name字段值为空值,返回True;否则返回False。
- setNull(int index): 设置当前记录中index字段值为空值。
- setNull(QString name):设置当前记录中name字段值为空值。
- clearValues():清除记录中所有字段的值,并将每个字段设置为空。
- setGenerated(int index, bool generated):将index字段的生成标志(generated flag)置位。
- setGenerated(QString name, bool generated):将name字段的生成标志(generated flag)置位。
- isGenerated(int index, bool generated):返回index字段的生成标志(generated flag)。
- isGenerated(QString name, bool generated):返回name字段的生成标志(generated flag)。
<wbr> <wbr> 添加记录到模型的示例代码:
con = QtSql.QSqlDatabase.addDatabase ('QSQLITE')
con.setDatabaseName ('data.sqlite')
con.open ()
stm = QtSql.QSqlTableModel ()
stm.setTable ('good')
stm.select ()
rec = con.record ('good')
rec.setValue ('goodname', 'Mouse pad')
rec.setValue ('goodcount', 3)
stm.insertRecord (-1, rec)
修改现有记录3的示例代码:
rec = stm.record(3)
rec.setValue('goodcount', 5)
stm.setRecord(3, rec)
QSqlTableModel类有以下信号:
- primeInsert(int row, QSqlRecord record):在当前活动数据库表的给定行中时,insertRows()触发。
- beforeInsert(QSqlRecord record):在当前活动数据库表中插入数据时,由insertRowIntoTable()触发。
- beforeUpdate(int row, QSqlRecord record):在row行记录更新前,由updateRowInTable()触发。
- beforeDelete(int row):在删除row行数据之前,由deleteRowFromTable()触发。
- dataChanged(QModelIndex topLeft, QModelIndex bottomRight[, QVector roles = QVector ()]): 模型中的数据变化时触发。如果受影响的数据属同一父类,其区域为topleft到bottomright。可选的roles参数用于指定哪些数据实际上已被修改, 该参数为空, 意味着所有数据都已修改。
<wbr> <wbr> <wbr>如果模型为OnManualSubmit编辑模式,那么dataChanged信号是调用submit()或submitAll()方法的理想场所。下列为数据库操作的相关代码,它不仅可以编辑,还可以通过按下相应的按钮来添加和删除记录。
from PyQt5 import QtCore, QtWidgets, QtSql
import sys
def addRecord ():
<wbr> <wbr> # 插入空记录,用户可手动输入 <wbr>
<wbr> <wbr> stm.insertRow (stm.rowCount ())
def delRecord ():
<wbr> <wbr> # 从模型中删除记录
<wbr> <wbr> stm.removeRow (tv.currentIndex (). row ())
<wbr> <wbr> # 重新加载数据到模型中
<wbr> <wbr> stm.select ()
app = QtWidgets.QApplication (sys.argv)
window = QtWidgets.QWidget ()
window.setWindowTitle ("QSqlTableModel")
Establish a connection to the database
con = QtSql.QSqlDatabase.addDatabase ('QSQLITE')
con.setDatabaseName ('data.sqlite')
con.open ()
Create a model
stm = QtSql.QSqlTableModel (parent = window)
stm.setTable ('good')
stm.setSort (1, QtCore.Qt.AscendingOrder)
stm.select ()
Set the headers for the columns of the model
stm.setHeaderData (1, QtCore.Qt.Horizontal, 'Name')
stm.setHeaderData (2, QtCore.Qt.Horizontal, 'Qty')
Set the table just created for the table
vbox = QtWidgets.QVBoxLayout ()
tv = QtWidgets.QTableView ()
tv.setModel (stm)
隐藏第一列
tv.hideColumn (0)
tv.setColumnWidth (1, 150)
tv.setColumnWidth (2, 60)
vbox.addWidget (tv)
btnAdd = QtWidgets.QPushButton ("添加记录(&A)")
btnAdd.clicked.connect (addRecord)
vbox.addWidget (btnAdd)
btnDel = QtWidgets.QPushButton ("删除记录(&A")
btnDel.clicked.connect (delRecord)
vbox.addWidget (btnDel)
window.setLayout (vbox)
window.resize (300, 250)
window.show ()
sys.exit (app.exec_ ())