美文网首页
PyQt5编程(45)—使用数据库(11)

PyQt5编程(45)—使用数据库(11)

作者: 用电热毯烤猪 | 来源:发表于2018-01-01 22:00 被阅读0次
    4.4 使用关联委托
    PyQt5编程(44)的程序有一个缺点,在添加新条目或编辑现有记录时,如果类别的输入不是代号而是“耗材”、“存储介质”时,所作的修改是不会被保存。因为该字段在数据库表中为整型字段,只能输入整数。
    为了改变这种情况,我们将被一个被称为连接(connected)的特殊委托(delegate)。它能够第一表中执行搜索,提取id字段内容并将其存储到第二个表的字段中。
    关联的委托功能由QSqlRelationalDelegate类实现。 继承层次结构如下:
    QObject - QAbstractltemDelegate - QltemDelegate - QSqlRelationalDelegate
    使用方法:
    1. 以要展示的组件(如,TableView)作参数创建QSqlRelationalDelegate类实例;
    2.调用setItemDelegate()、setItemDelegateForColumn()或setItemDelegateForRow()。
    PyQt5中有个BUG, 在修改使用委托的某列值,并将焦点移到另一记录时,有时会显示id而非显示指定值的情况。要绕开此BUG,需要按如下操作:
    1.把展示组件(TableView)的编辑模式设置为onManualSubmit;
    2.处理dataChanged信号,调用submit()或submitAll()来实现修改的数据存储到数据库。
    

    下面是 PyQt5编程(44)中的例子使用关联委托后的代码:

    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("QRelationalSqlTableModel")
    con = QtSql.QSqlDatabase.addDatabase('QSQLITE')
    con.setDatabaseName('data.sqlite')
    con.open()
    stm = QtSql.QSqlRelationalTableModel(parent = window)
    stm.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
    stm.setTable('good')
    stm.setSort(2, QtCore.Qt.AscendingOrder)

    将good表中的category字段设置为到category表的链接

    stm.setRelation(3, QtSql.QSqlRelation('category', 'id', 'catname'))
    stm.select()
    stm.setHeaderData(1, QtCore.Qt.Horizontal, '名称')
    stm.setHeaderData(2, QtCore.Qt.Horizontal, '数量')
    stm.setHeaderData(3, QtCore.Qt.Horizontal, '类别')
    stm.dataChanged.connect(stm.submitAll)
    vbox = QtWidgets.QVBoxLayout()
    tv = QtWidgets.QTableView()
    tv.setModel(stm)
    tv.setItemDelegateForColumn(3, QtSql.QSqlRelationalDelegate(tv))
    tv.hideColumn(0)
    tv.setColumnWidth(1, 150)
    tv.setColumnWidth(2, 60)
    tv.setColumnWidth(3, 150)
    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(430, 250)
    window.show()
    sys.exit(app.exec_())

    图片.png

    相关文章

      网友评论

          本文标题:PyQt5编程(45)—使用数据库(11)

          本文链接:https://www.haomeiwen.com/subject/cndxnxtx.html