QSortFilterProxyModel uses columnCount() from sourceModel() instead of its own columnCount() implementation.
This becomes an issue when the sourceModel()'s columnCount() returns a smaller number then the QSortFilterProxyModel's columnCount(). This issue happens only with data(). headerData() works as expected. This results in a table having the correct number of columns but empty cells.
The other way round (sourceModel()->columnCount() > columnCount()) it is basically the same issue, but because the headerData() works correctly, the issue is "invisible".
Attached you'll find a zip archive, containing a sample project demonstrating the issue. Check BaseModel::rowCount()'s comments for fastest start-up.