基于 QSqlTableModel 就地编辑新记录的 QTableView 不会在 PyQt 中保存编辑
Posted
技术标签:
【中文标题】基于 QSqlTableModel 就地编辑新记录的 QTableView 不会在 PyQt 中保存编辑【英文标题】:QTableView based on QSqlTableModel editing new record in place doesn’t save edits in PyQt 【发布时间】:2020-06-25 10:50:19 【问题描述】:我有一个 QTableView 的表单有一个添加新记录的按钮。记录出现,但我输入的任何数据都没有保存。事实上,一旦我添加了一条记录,就不会保存对 tableview 的任何编辑。只要不添加新记录,我就可以就地编辑。底层数据库是 Postgresql。
问题是,如何添加可以立即编辑的新记录?我在下面的代码中缺少什么?
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
from phones import *
app=QApplication(sys.argv)
QTableView
QSqlTableModel
class Main(QMainWindow):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.cont_id = '9'
self.populate_phones()
self.ui.new_phone.clicked.connect(self.add_phone)
def populate_phones(self):
self.phone_model = QSqlTableModel(self)
self.phone_model.setTable("contact_phones")
self.phone_model.setFilter("contact_id='0'".format(self.cont_id))
self.phone_model.select()
self.phone_view = self.ui.phone_view
self.phone_view.setModel(self.phone_model)
self.phone_view.resizeColumnsToContents()
def add_phone(self):
self.phone_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
row = self.phone_model.rowCount()
record = self.phone_model.record()
record.setGenerated('id', False) #primary key
record.setValue('contact_id', self.cont_id) #foreign key
self.phone_model.insertRecord(row, record)
submit = self.phone_model.submitAll()
#self.phone_model.select()
phone_index_edit = QModelIndex(self.phone_model.index(row, self.phone_model.fieldIndex('phone_number')))
self.ui.phone_view.edit(phone_index_edit)
if __name__=="__main__":
db = QSqlDatabase.addDatabase("QPSQL");
db.setHostName(server)
db.setDatabaseName(database)
db.setUserName(user)
db.setPassword(pword)
myapp = Main()
myapp.show()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:您正在将编辑策略设置为OnManualSubmit
:
在调用 submitAll() 或 revertAll() 之前,所有更改都将缓存在模型中。
一旦您通过调用edit()
开始编辑,将不会保存任何更改,而只会缓存。如果您关闭小部件之前没有调用submitAll()
,这些更改将丢失;当您尝试添加新字段时也会发生这种情况,因为insertRecord
将仅提交插入记录的更改,而丢弃以前缓存的更改。
您可以保留默认的OnRowChange
编辑策略,或使用OnFieldChange
。
关于您的代码的进一步说明:
QApplication
实例的创建应该在 if __name__
块内进行(开头的 QTableView
和 QSqlTableModel
行不应该在那里,因为它们什么都不做);
你调用的是QWidget的__init__
,但是Main
是QMainWindow的子类;您应该使用 QMainWindow.__init__(self)
或 QWidget 的子类;
由于您不会使用OnManualSubmit
策略,因此无需在insertRecord
之后提交;
没有必要创建一个新的 QModelIndex 实例,因为model.index()
已经返回了一个 QModelIndex;
【讨论】:
我已根据您的建议更新了我的代码。有些马虎是不好的剪切和粘贴,但你的建议真的很有帮助。我已经编辑了我的代码。 如果建议的答案不能完全解决您的问题,请使用 cmets 指定正在发生的事情以及预期的行为。 切勿根据答案修改您的问题:这会使问题和答案都变得混乱。以上是关于基于 QSqlTableModel 就地编辑新记录的 QTableView 不会在 PyQt 中保存编辑的主要内容,如果未能解决你的问题,请参考以下文章