[PyQt] rowCount() on a QSqlTableModel being erratic

Simon Hibbs simon.hibbs at gmail.com
Sun Jan 31 23:26:01 GMT 2010


I have a browser window with a QTableView on a QSqlTableModel and a
button to remove the selected row. This works fine. If I call
self.model.rowCount() before and after the
self.model.removeRow(index.row()) they return the expected number of
rows - one less after the removal.

I also have a QGraphicsScene displaying one item for each row in the
model. I have subscribed a refresh method in the scene to the
rowsRemoved signal for the model.

When I initialise the scene it calls the refresh method and it works
as intended. self.model.rowCount() returns the correct vale so I ca
iterate over the rows in the model. When I delete a row in the browser
window the rowsRemoved signal is sent, the scene's refresh method is
triggered, but self.model.rowCount() returns zero regardles of how
many rows there are. Calling rowCount() in the browser code
immediately after the removeRow call stll returns the correct value.
I've poured through all the documentation and checked my code against
the Rapid Gui Programming book and it all looks fine.

Any idea why rowCount would return zero in a method called due to a
rowsRemoved signal, but works fine after the triggering removeRow
method call completes? I'm not re-implementing removeRow, it the
default implementation for a QSqlTableModel.

There is one oddity in the documentation. For
QAbstractItemModel.rowCount the documentations says that:

"Note: When implementing a table based model, rowCount() should return
0 when the parent is valid."

I think for a table model the parent is suposed to be invalid, so
perhas this is a case of the model state not being quite correct at
the point the signal is being sent?

I just verified this using a slight modification of the tablemodel.pyw
example in the sql examples directory on Windows. To test, rename it
tablemodel.py and add the following function.

def checkNumRows(x,y):
    print "On signal rows = ", model.rowCount()

Then the following code before sys.exit(app.exec_()):

    QtCore.QObject.connect(model,
            QtCore.SIGNAL("rowsRemoved(QModelIndex, int, int)"),
            checkNumRows)

    model.removeRow(2)
    model.submitAll()

    print "After submitAll rows = ", model.rowCount()

Then run the example from the command line. "On signal rows" will be 0
while "After SubmitAll rows" is 4. Because the edit strategy is
OnManualSubmit the rowsRemoved signal is only sent on submitAll().

Simon Hibbs


More information about the PyQt mailing list