Зафиксировать изменения модели QSqlRelationalTableModel в базе данных

Я изменил модель реляционной таблицы по адресу https://doc.qt.io/qt-5/qtsql-relationaltablemodel-relationaltablemodel-cpp.html

Я хочу сохранить свои изменения в своей базе данных, но она сохраняет только первые два столбца, а не строку поиска первичного ключа. Кроме того, я не могу удалить строки. Я искал, но не нашел никакой информации о том, как это сделать. Что я делаю неправильно?

Пример данных, которые я использую:

CREATE TABLE `category` ( `Id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `DrinkType` TEXT NOT NULL);
INSERT INTO `category` VALUES (1,'Non-alcoholic');
INSERT INTO `category` VALUES (2,'Alcoholic');
CREATE TABLE "drinks" ( `Id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `Name` TEXT NOT NULL, `Type` INTEGER );
INSERT INTO `drinks` VALUES (1,'Coca Cola',1);
INSERT INTO `drinks` VALUES (2,'Pilsner',2);

Мой код:

def addRecord():
    model.insertRow(model.rowCount())

def delRecord():
    model.removeRow(view.currentIndex().row())
    model.select()

app = QtWidgets.QApplication(sys.argv)

window = QtWidgets.QWidget()
window.setWindowTitle("QRelationalSqlTableModel")

con = QtSql.QSqlDatabase.addDatabase('QSQLITE')
con.setDatabaseName('drinks.db')
con.open()

model = QtSql.QSqlRelationalTableModel(parent = window)
model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
model. setTable('drinks')
model.setRelation(2, QtSql.QSqlRelation('category', 'id', 'drinktype'))
model.select()

model.setHeaderData(1, QtCore.Qt.Horizontal, 'Name')
model.setHeaderData(3, QtCore.Qt.Horizontal, 'Type of drink')

vbox = QtWidgets.QVBoxLayout()

view = QtWidgets.QTableView()
view.setModel(model)
view.setItemDelegate(QtSql.QSqlRelationalDelegate(view))
view.hideColumn(0)
view.setColumnWidth(1, 150)
view.setColumnWidth(2, 150)

vbox.addWidget(view)
btnAdd = QtWidgets.QPushButton("&Add record")
btnAdd.clicked.connect(addRecord)
vbox.addWidget(btnAdd)
btnDel = QtWidgets.QPushButton("&Delete record")
btnDel.clicked.connect(delRecord)
vbox.addWidget(btnDel)

window.setLayout(vbox)
window.resize(430, 250)
window.show()
sys.exit(app.exec_())

1 ответ

Решение

Одна из проблем заключается в том, что вы используете неуместную стратегию, если вы используете OnManualSubmit Вы должны вызвать метод submitAll() чтобы изменения записывались в базу данных, если вы не хотите это делать, лучше использовать OnRowChange, с этой стратегией изменения будут сделаны, когда после добавления значений давлений введите или выберите другую строку.

Если вы хотите удалить строку из базы данных, вы должны использовать deleteRowFromTable(), ты используешь removeRow() но это удаляет только строку в представлении, но не в базе данных, поэтому через мгновение данные обновляются, показывая новую строку.

def addRecord():
    model.insertRow(model.rowCount())
    view.scrollToBottom()

def delRecord():
    model.deleteRowFromTable(view.currentIndex().row())
    model.select()

app = QtWidgets.QApplication(sys.argv)

window = QtWidgets.QWidget()
window.setWindowTitle("QRelationalSqlTableModel")

con = QtSql.QSqlDatabase.addDatabase('QSQLITE')
con.setDatabaseName('drinks.db')
con.open()

model = QtSql.QSqlRelationalTableModel(parent = window)
model.setEditStrategy(QtSql.QSqlTableModel.OnRowChange)
model. setTable('drinks')
model.setRelation(2, QtSql.QSqlRelation('category', 'id', 'drinktype'))
model.select()

model.setHeaderData(1, QtCore.Qt.Horizontal, 'Name')
model.setHeaderData(3, QtCore.Qt.Horizontal, 'Type of drink')

vbox = QtWidgets.QVBoxLayout()

view = QtWidgets.QTableView()
view.setModel(model)
view.setItemDelegate(QtSql.QSqlRelationalDelegate(view))
view.hideColumn(0)
view.setColumnWidth(1, 150)
view.setColumnWidth(2, 150)

vbox.addWidget(view)
btnAdd = QtWidgets.QPushButton("&Add record")
btnAdd.clicked.connect(addRecord)
vbox.addWidget(btnAdd)
btnDel = QtWidgets.QPushButton("&Delete record")
btnDel.clicked.connect(delRecord)
vbox.addWidget(btnDel)

window.setLayout(vbox)
window.resize(430, 250)
window.show()
sys.exit(app.exec_())
Другие вопросы по тегам