Hello,

Is there a way to specify a default value for a Data Widget Mapper if a user leaves a mapped field empty? The mapper appears to ignore the db schema's default declarations. Ideally, I'd like to insert Null. Something analogous to this:

        test=# INSERT INTO gear (name, addr) VALUES ('qwe', Null);


My test case example has a table with a MACADDR field. There are times when a user would enter a valid macaddr and times when the macaddr field should be left blank. Note that the QSQLITE driver happily allows the field to be filled-in or not. But the QPSQL driver appears to validate the macaddr field. When empty, this causes the mapper's model to fail with an invalid input syntax error on submitAll(). eg:

ERROR: invalid input syntax for type macaddr: "" QPSQL: Unable to create query

Attached please find a simple example program, mapperTest.py, and a db schema file, test_db.sql. (Not sure how to combine the two into a single .py file.) To recreate the db from the cmd-line:

        % createdb test
        % psql test < test_db.sql

Thanks in advance!
Scott



#!/usr/bin/env python


#-------------------------------------------------------------------------------
# imports
#-------------------------------------------------------------------------------
import sys, os
from PyQt4 import QtCore, QtGui, QtSql

MAC		   = "qt_mac_set_native_menubar" in dir()

# table field enumeration
ID, NAME, ADDR = range(3)



#-------------------------------------------------------------------------------
# class
#-------------------------------------------------------------------------------
class MapperTest(QtGui.QDialog):

	def __init__(self, parent=None):
		QtGui.QDialog.__init__(self)



		# init
		# ------------------------------------------------
		self.theFrame		    = QtGui.QFrame()
		self.theFrame.setFrameStyle(QtGui.QFrame.StyledPanel|QtGui.QFrame.Sunken)



		# type group
		# ------------------------------------------------
		self.typeGroup          = QtGui.QGroupBox()

		self.nameLabel  	    = QtGui.QLabel(self.tr("Name"))
		self.nameEdit           = QtGui.QLineEdit()

		self.addrLabel  	    = QtGui.QLabel(self.tr("MAC"))
		self.addrEdit           = QtGui.QLineEdit()


		# layout
		self.typeLayout   = QtGui.QGridLayout()

		self.typeLayout.addWidget(self.nameLabel,            0, 0)
		self.typeLayout.addWidget(self.nameEdit,             0, 1)

		self.typeLayout.addWidget(self.addrLabel,            1, 0)
		self.typeLayout.addWidget(self.addrEdit,             1, 1)

		self.typeGroup.setLayout(self.typeLayout)

		

		# data model
		# ------------------------------------------------
		self.theModel           = QtSql.QSqlRelationalTableModel(self)
		self.theModel.setTable("gear")

		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(ADDR, QtCore.Qt.Horizontal, QtCore.QVariant("ADDR"))

		select = self.theModel.select()
		print "theModel select: ", select
		print self.theModel.lastError().text()



		# data widget mapper
		# ------------------------------------------------
		self.mapper				= QtGui.QDataWidgetMapper(self)
		self.mapper.setSubmitPolicy(QtGui.QDataWidgetMapper.ManualSubmit)
		self.mapper.setModel(self.theModel)
		self.mapper.setItemDelegate(QtSql.QSqlRelationalDelegate(self))

		self.mapper.addMapping(self.nameEdit, NAME)
		self.mapper.addMapping(self.addrEdit, ADDR)

		self.mapper.toFirst()


		
		# buttons
		# ------------------------------------------------		
		self.newButton	        = QtGui.QPushButton("New")
		self.delButton	        = QtGui.QPushButton("Delete")
		self.commitButton		= QtGui.QPushButton("Commit")

		# disable delete button by default
		self.delButton.setEnabled(False)

		# buttons don't get tabbing focus on non-OSX platforms
		if not MAC:
			self.newButton.setFocusPolicy(QtCore.Qt.NoFocus)
			self.delButton.setFocusPolicy(QtCore.Qt.NoFocus)
			self.commitButton.setFocusPolicy(QtCore.Qt.NoFocus)


		# button group layout
		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.typeGroup)
		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.commit)




	# methods
	# ------------------------------------------------

	def commit(self):
		print "commit() ..."
		row		    = self.mapper.currentIndex()
		submit	    = self.mapper.submit()
		print "mapper: ", submit
		if submit == False:
			print self.theModel.lastError().text()

		self.mapper.setCurrentIndex(row)

		submit	    = self.theModel.submitAll()
		print "model:  ", submit
		if submit == False:
			print self.theModel.lastError().text()

		

		

	def newRecord(self):
		print "newRecord() ..."
		
		row         = self.theModel.rowCount()
		submit      = self.mapper.submit()
		self.theModel.insertRow(row)
		self.mapper.setCurrentIndex(row)

		self.nameEdit.setFocus()



	def deleteRecord(self):
		print "deleteRecord() ..."



		


#-------------------------------------------------------------------------------
# main
#-------------------------------------------------------------------------------
if __name__ == "__main__":

	app  = QtGui.QApplication(sys.argv)

#	filename = os.path.join(os.path.dirname(__file__), "test.db")
#	create = not QtCore.QFile.exists(filename)
#	db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
#	db.setDatabaseName(filename)

	db		  = QtSql.QSqlDatabase.addDatabase("QPSQL")
	db.setDatabaseName("test")
	
	
	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

	form = MapperTest()
	form.setWindowTitle("Mapper Test")
	form.show()
	sys.exit(app.exec_())



Attachment: test_db.sql
Description: Binary data

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Reply via email to