На этом шаге мы рассмотрим класс QSqlRecord и перечислим сигналы класса QSqlTableModel.
Методы insertRecord() и setRecord(), предназначенные, соответственно, для добавления и изменения записи, принимают в качестве второго параметра экземпляр класса QSqlRecord. Чтобы создать этот экземпляр, нам следует знать формат вызова конструктора класса. Вот он:
<Объект> = QSqlRecord([<QSqlRecord>])
Если в параметре указать экземпляр класса QSqlRecord, будет создана его копия. Обычно при создании новой записи здесь указывают значение, возвращенное методом record() класса QSqlDatabase (оно хранит сведения о структуре таблицы и, следовательно, представляет пустую запись), а при правке существующей записи - значение, возвращенное методом record(), который унаследован классом QSqlTableModel от класса QSqlQueryModel (оно представляет запись, которую нужно отредактировать).
Класс QSqlRecord, в дополнение к методам, рассмотренным нами на 161 шаге, поддерживает следующие методы:
Пример кода, добавляющего новую запись в модель:
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', 'Коврик для мыши') rec.setValue('goodcount', 3) stm.insertRecord(-1, rec)
Пример кода, редактирующего существующую запись с индексом 3:
rec = stm.record(3)
rec.setValue('goodcount', 5)
stm.setRecord(3, rec)
Класс QSqlTableModel поддерживает такие сигналы:
Сигнал dataChanged - идеальное место для вызова методов submit() или submitAll() в случае, если для модели был задан режим редактирования OnManualSubmit. Как мы знаем, эти методы выполняют сохранение отредактированных данных в базе.
В примере ниже представлен код тестового складского приложения, позволяющего не только править, но и добавлять и удалять записи нажатием соответствующих кнопок. А на рисунке 1 можно увидеть само это приложение в работе.
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") # Устанавливаем соединение с базой данных con = QtSql.QSqlDatabase.addDatabase('QSQLITE') con.setDatabaseName('c:\\temp\\data.sqlite') con.open() # Создаем модель stm = QtSql.QSqlTableModel(parent=window) stm.setTable('good') stm.setSort(1, QtCore.Qt.AscendingOrder) stm.select() # Задаем заголовки для столбцов модели stm.setHeaderData(1, QtCore.Qt.Horizontal, 'Название') stm.setHeaderData(2, QtCore.Qt.Horizontal, 'Кол-во') # Задаем для таблицы только что созданную модель 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("&Добавить запись") btnAdd.clicked.connect(addRecord) vbox.addWidget(btnAdd) btnDel = QtWidgets.QPushButton("&Удалить запись") btnDel.clicked.connect(delRecord) vbox.addWidget(btnDel) window.setLayout(vbox) window.resize(300, 250) window.show() sys.exit(app.exec_())
Рис.1. Пример складского приложения, использующего модель QSqlTableModel
На следующем шаге мы рассмотрим модель, поддерживающую межтабличные связи.