View Full Version : QDataWidgetMapper: setCurrentIndex causes GUI to hang

15th December 2011, 20:27
I have been building a GUI data-entry application that accepts input from a user and saves it to a database. I have been using PyQt to develop the application, which has been quite the learning experience for me, but one that I have negotiated well with the help of Mark Summerfield's book (which I recommend). However, I have encountered a problem that truly frustrates me.

I have a data entry dialog in which I am implementing a QSqlRelationalTableModel object for the database model and a QDataWidgetMapper object to map the widget states to it. When I press the Add Entry button in my dialog, the current record gets saved if there are any changes and a new row is written to the data model. I've set this up for all of the other dialogs in my application and it works without any problems. But in this dialog, when the execution hits self.mapper.setCurrentIndex(row), the GUI hangs and forces me to end the process through the process manager. I've verified that the mapper is pointing to the model and that a new row is indeed being written to the model. I do not know why the code is not working when I have used exactly the same code for other implementations without any problems.

For the record, I am using PyQt 4.7.2/Qt 4.6.2 with Python 2.6.5 on a Ubuntu Linux machine (64-bit version 10.04 Lucid Lynx).

Here is the code in the class constructor:

# underlying database model (tbl_penaltyshootouts)
# because of foreign keys, instantiate QSqlRelationalTableModel and define relations to it
self.model = QSqlRelationalTableModel(self)
self.model.setRelation(PenShootoutEntryDlg.ROUND_I D, QSqlRelation("tbl_rounds", "round_id", "round_desc"))
self.model.setRelation(PenShootoutEntryDlg.LINEUP_ ID, QSqlRelation("lineup_list", "lineup_id", "player"))
self.model.setRelation(PenShootoutEntryDlg.OUTCOME _ID, QSqlRelation("tbl_penoutcomes", "penoutcome_id", "po_desc"))
self.model.setSort(PenShootoutEntryDlg.ID, Qt.AscendingOrder)

# define mapper
# establish ties between underlying database model and data widgets on form
self.mapper = QDataWidgetMapper(self)
self.mapper.setSubmitPolicy(QDataWidgetMapper.Manu alSubmit)
penaltyDelegate = GenericDelegate(self)
penaltyDelegate.insertColumnDelegate(PenShootoutEn tryDlg.LINEUP_ID, ShootoutPlayerComboBoxDelegate(self))
penaltyDelegate.insertColumnDelegate(PenShootoutEn tryDlg.ROUND_ID, ShootoutRoundComboBoxDelegate(self))

self.connect(self.addEntry, SIGNAL("clicked()"), self.addRecord)

Here is the addRecord() code:

def addRecord(self):
"""Adds new record at end of entry list."""
# save current index if valid
row = self.mapper.currentIndex()
if row != -1:
if self.isDirty(row):
if MsgPrompts.SaveDiscardOptionPrompt(self):
if not self.mapper.submit():
MsgPrompts.DatabaseCommitErrorPrompt(self, self.model.lastError())
if row == 0:
self.updateLinkingTable(self.penOpenerMapper, self.penFirstSelect)

row = self.model.rowCount()

If you want or need to see more code, let me know.

16th December 2011, 00:58
I found the source of the hanging GUI. It turns out to have nothing to do with the mapper - there was an infinite loop going on in one of the item delegates!

Now I feel a bit silly...:o

16th December 2011, 05:33
We all have those moments... why do you think you should be any different? ;)