我正在通过QSqlRelationalTableModel将SQLite数据库中的行显示到QTreeView中。
编辑策略设置为OnManualSubmit
。
我正在编辑对话框中的数据行,并使用setRecord(row_index, record)
更新模型-确定。
问题:当我在更改后的QSqlRelationalTableModel上执行SubmitAll()时,所做的更改未写入SQLite数据库文件中。 即使似乎没有发生SQL错误。
预期结果:我所做的更改应永久存储在SQLite数据库文件中。
注意:在主要部分的第二次运行中,注释掉create_sample_data()
的调用。
最小但完整的工作代码示例:
#!/usr/bin/env python3
# coding = utf-8
import sys
import re
from PyQt5 import QtWidgets, QtGui, QtCore, QtSql
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("test_2.db");
modelQuery = QtSql.QSqlQueryModel()
modelTable = QtSql.QSqlRelationalTableModel()
class dlgDetail(QtWidgets.QDialog):
def __init__(self, index, parent):
QtWidgets.QDialog.__init__(self, parent=None)
self.setupUi(self)
# connect signals
self.accepted.connect(self.dlgDetail_accepted)
self.pbNew.clicked.connect(self.on_my_pbNew_clicked)
self.pbSave.clicked.connect(self.on_my_pbSave_clicked)
self.pbDel.clicked.connect(self.on_my_pbDel_clicked)
# load selected data
self.row_ix = index.row()
self.model = parent.treeView.model()
ix = self.model.index(self.row_ix, 0) # column which contains the id
self.efId.setText(ix.data())
ix = self.model.index(self.row_ix, 1) # column which contains the lastName
self.efLastName.setText(ix.data())
ix = self.model.index(self.row_ix, 2) # column which contains the firstName
self.efFirstName.setText(ix.data())
def setupUi(self, parent):
self.setGeometry(300,200,250,200)
lblId = QtWidgets.QLabel(self)
lblId.setText("ID:")
lblLastName = QtWidgets.QLabel(self)
lblLastName.setText("Last Name:")
lblLastName.move(0,30)
lblFirstName = QtWidgets.QLabel(self)
lblFirstName.setText("First Name:")
lblFirstName.move(0,60)
self.efId = QtWidgets.QLineEdit(self)
self.efId.move(100,0)
self.efLastName = QtWidgets.QLineEdit(self)
self.efLastName.move(100,30)
self.efFirstName = QtWidgets.QLineEdit(self)
self.efFirstName.move(100,60)
self.pbNew = QtWidgets.QPushButton("New", self)
self.pbNew.move(0,150)
self.pbSave = QtWidgets.QPushButton("Save", self)
self.pbSave.move(75,150)
self.pbDel = QtWidgets.QPushButton("Del", self)
self.pbDel.move(150,150)
def dlgDetail_accepted(self):
record = modelTable.record()
record.setGenerated(self.row_ix, False)
record.setValue("persId", self.efId.text())
record.setValue("lastName", self.efLastName.text())
record.setValue("firstName", self.efFirstName.text())
# Update Database
if not modelTable.submitAll():
print("Update Database - Error: ", modelTable.lastError().text())
else:
print("Update Database - Success.")
# Update Model
modelTable.setRecord(self.row_ix, record)
def on_my_pbSave_clicked(self):
self.dlgDetail_accepted()
self.close()
def on_my_pbNew_clicked(self):
pass
def on_my_pbDel_clicked(self):
pass
class winMain(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi()
self.setGeometry(300,200,700,500)
self.treeView.doubleClicked.connect(self.OnEditData)
self.show()
def OnEditData(self, index):
dlg_detail = dlgDetail(index, self)
dlg_detail.exec_()
def setupUi(self):
self.centralwidget = QtWidgets.QWidget(self)
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView.setRootIsDecorated(False)
self.treeView.setSortingEnabled(True)
self.treeView.setAlternatingRowColors(True)
self.treeView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.treeView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.treeView.header().setStretchLastSection(True)
self.horizontalLayout.addWidget(self.treeView)
self.setCentralWidget(self.centralwidget)
modelTable.setTable("person")
modelTable.setRelation(3, QtSql.QSqlRelation("country", "id", "name"));
modelTable.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
modelTable.select()
modelTable.setHeaderData(0, QtCore.Qt.Horizontal, "ID");
modelTable.setHeaderData(1, QtCore.Qt.Horizontal, "Last Name");
modelTable.setHeaderData(2, QtCore.Qt.Horizontal, "First Name");
modelTable.setHeaderData(3, QtCore.Qt.Horizontal, "Country");
self.treeView.setModel(modelTable)
def create_sample_data():
# create tables for our model
modelQuery.setQuery("""CREATE TABLE IF NOT EXISTS country (
id INTEGER PRIMARY KEY UNIQUE,
name TEXT
)""")
modelQuery.setQuery("""CREATE TABLE IF NOT EXISTS person (
persId TEXT,
lastName TEXT,
firstName TEXT,
country_id INTEGER,
FOREIGN KEY (country_id) REFERENCES country(id)
)""")
# create some sample data for our model
modelQuery.setQuery("INSERT INTO country (id, name) VALUES (1, 'Angola')")
modelQuery.setQuery("INSERT INTO country (id, name) VALUES (2, 'Serbia')")
modelQuery.setQuery("INSERT INTO country (id, name) VALUES (3, 'Georgia')")
modelQuery.setQuery("INSERT INTO person (persId, lastName, firstName, country_id) VALUES ('1001', 'Martin', 'Robert', 1)")
modelQuery.setQuery("INSERT INTO person (persId, lastName, firstName, country_id) VALUES ('1002', 'Smith', 'Brad', 2)")
modelQuery.setQuery("INSERT INTO person (persId, lastName, firstName, country_id) VALUES ('1003', 'Smith', 'Angelina', 3)")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
# comment the following call in, on the 2nd run:
create_sample_data()
window = winMain()
sys.exit(app.exec_())