Hi all,
Can anyone please help shed light on why methods performed on a
QSqlRecord object would cause bus error crashes?
I'm trying to view data before it's written to my database.
Connecting to my table model's beforeUpdate signal provides me with
access to the QSqlRecord for the updating row. The problem is that
calling count() or isEmpty(), let alone anything more interesting,
causes my app to crash with a bus error.
The salient pieces look like this:
self.theModel = QtSql.QSqlTableModel(self)
self.theModel.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.connect(self.theModel, QtCore.SIGNAL("beforeUpdate(int,
QSqlRecord &)"), self.test)
def test(self, row, record):
print "test() ...", row
print "count: ", record.count()
See the attached sample app, line 112, for a working example. The app
crashes when the "commit" button is pressed, as it ponders
record.count() on line 117.
Thanks in advance!
#!/usr/bin/env python
def createData():
print "createData() ..."
query = QtSql.QSqlQuery()
query.exec_("DROP TABLE color")
query.exec_("""CREATE TABLE color (
color_id PRIMARY KEY,
name VARCHAR(32) UNIQUE NOT NULL,
description TEXT NOT NULL)""")
query.exec_("INSERT INTO color (name, description) "
"VALUES ('red', 'this is red')")
query.exec_("INSERT INTO color (name, description) "
"VALUES ('green', 'this is green')")
query.exec_("INSERT INTO color (name, description) "
"VALUES ('blue', 'this is blue')")
import sys
from PyQt4 import QtCore, QtGui, QtSql
MAC = "qt_mac_set_native_menubar" in dir()
ID, NAME, DESC = range(3)
class BeforeUpdateTest(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self)
self.theFrame = QtGui.QFrame()
self.theFrame.setFrameStyle(QtGui.QFrame.StyledPanel|QtGui.QFrame.Sunken)
self.nameGroup = QtGui.QGroupBox()
self.nameLabel = QtGui.QLabel(self.tr("Name"))
self.nameEdit = QtGui.QLineEdit()
self.descLabel = QtGui.QLabel(self.tr("Description"))
self.descEdit = QtGui.QLineEdit()
self.nameLayout = QtGui.QGridLayout()
self.nameLayout.addWidget(self.nameLabel, 0, 0)
self.nameLayout.addWidget(self.nameEdit, 0, 1)
self.nameLayout.addWidget(self.descLabel, 1, 0)
self.nameLayout.addWidget(self.descEdit, 1, 1)
self.nameGroup.setLayout(self.nameLayout)
# data model
self.theModel = QtSql.QSqlTableModel(self)
self.theModel.setTable("color")
self.theModel.setSort(NAME, QtCore.Qt.AscendingOrder)
self.theModel.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.theModel.setHeaderData(ID, QtCore.Qt.Horizontal, QtCore.QVariant("ID"))
self.theModel.setHeaderData(NAME, QtCore.Qt.Horizontal, QtCore.QVariant("NAME"))
self.theModel.setHeaderData(DESC, QtCore.Qt.Horizontal, QtCore.QVariant("DESC"))
select = self.theModel.select()
# data widget mapper
self.mapper = QtGui.QDataWidgetMapper(self)
self.mapper.setSubmitPolicy(QtGui.QDataWidgetMapper.ManualSubmit)
self.mapper.setModel(self.theModel)
self.mapper.addMapping(self.nameEdit, NAME)
self.mapper.addMapping(self.descEdit, DESC)
self.mapper.toFirst()
# buttons
self.newButton = QtGui.QPushButton("New")
self.delButton = QtGui.QPushButton("Delete")
self.delButton.setEnabled(False)
self.commitButton = QtGui.QPushButton("Commit")
if not MAC:
self.newButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.delButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.commitButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.buttonGroup = QtGui.QGroupBox()
self.buttonLayout = QtGui.QHBoxLayout()
self.buttonLayout.addStretch()
self.buttonLayout.addWidget(self.newButton)
self.buttonLayout.addWidget(self.delButton)
self.buttonLayout.addWidget(self.commitButton)
self.buttonLayout.addStretch()
self.buttonGroup.setLayout(self.buttonLayout)
# main layout
self.widgetLayout = QtGui.QVBoxLayout()
self.widgetLayout.addWidget(self.nameGroup)
self.widgetLayout.addWidget(self.buttonGroup)
self.widgetLayout.addStretch()
self.formLayout = QtGui.QHBoxLayout()
self.formLayout.addLayout(self.widgetLayout)
self.theFrame.setLayout(self.formLayout)
self.theLayout = QtGui.QVBoxLayout()
self.theLayout.addWidget(self.theFrame)
self.setLayout(self.theLayout)
# signals/slots
self.connect(self.newButton, QtCore.SIGNAL("clicked()"), self.newRecord)
self.connect(self.commitButton, QtCore.SIGNAL("clicked()"), self.saveRecord)
self.connect(self.theModel, QtCore.SIGNAL("beforeUpdate(int, QSqlRecord &)"), self.test)
def test(self, row, record):
print "test() ...", row
print "count: ", record.count()
def saveRecord(self):
row = self.mapper.currentIndex()
submit = self.mapper.submit()
self.mapper.setCurrentIndex(row)
modelErr = self.theModel.submitAll()
# get query string from the model
theQuery = self.theModel.query()
print "query: ", theQuery.lastQuery()
def newRecord(self):
row = self.theModel.rowCount()
submit = self.mapper.submit()
self.theModel.insertRow(row)
self.mapper.setCurrentIndex(row)
self.nameEdit.setFocus()
# main
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(":memory:")
if not db.open():
QtGui.QMessageBox.warning(None, "Foo",
QtCore.QString("Database Error: %1").arg(db.lastError().text()))
sys.exit(1)
ok = db.open()
# print "db connection: ", ok
createData()
form = BeforeUpdateTest()
form.setWindowTitle("BeforeUpdate Test")
form.show()
sys.exit(app.exec_())
_______________________________________________
PyQt mailing list [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt