Шаг 173.
Библиотека PyQt5. Работа с базами данных. Выполнение SQL-запросов... . Модели, связанные с данными. Модель, связанная с таблицей (окончание)

    На этом шаге мы рассмотрим класс 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

    На следующем шаге мы рассмотрим модель, поддерживающую межтабличные связи.




Предыдущий шаг Содержание Следующий шаг