The form where I have a QTableView has a button to add a new record. The record appears but any data I type in is not saved. In fact, once I add a record, no edits to the tableview are saved. I can edit in place as long as I do not add a new record. The underlying database is Postgresql.
The question is, how do I add a new record which can be edited immediately? What am I missing in the code below?
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_())
You are setting the edit strategy to OnManualSubmit
:
All changes will be cached in the model until either submitAll() or revertAll() is called.
Once you start editing by calling edit()
no change will be saved, but only cached. If you close the widget without calling submitAll()
before, those changes will be lost; this also happens when you try to add a new field, because insertRecord
will submit only the changes for the inserted record while discarding previous cached changes.
You can just leave the default OnRowChange
edit strategy, or use OnFieldChange
.
Further notes about your code:
QApplication
instance should happen within the if __name__
block (and those QTableView
and QSqlTableModel
lines at the beginning shouldn't be there, as they do nothing);__init__
of QWidget, but Main
is a subclass of QMainWindow; you should either use QMainWindow.__init__(self)
or subclass from QWidget;OnManualSubmit
strategy, there is no need to submit after insertRecord
;model.index()
already returns a QModelIndex;