QTableView with QAbstractTableModel derrived class not displaying data
-
I am trying to use a QTableView to display information using a class derived from QAbstractTableModel, but it is not displaying and using debug lines I have confirmed that data() is never being called.
I've looked at numerous versions of this problem but so far have not found a solution for my situation - unlike many I have looked at, I am not creating either the view or model on the stack.
The QListView itself is defined in MainWindow.ui - it is a child of a QHBoxLayout that is a child of a centalwidget of the QMainWindow.
First here is the declaration for the model, RailDocModel:
class RailDocModel : public QAbstractTableModel { Q_OBJECT private: QList<LayoutObject *> Elements; public: enum RailDocRoles { SampleRole = Qt::UserRole, }; explicit RailDocModel( QObject * = nullptr ); int columnCount( const QModelIndex & = QModelIndex() ) const override; int rowCount( const QModelIndex & = QModelIndex() ) const override; QVariant data( const QModelIndex &, int ) const override; QVariant headerData( int, Qt::Orientation, int ) const; void operator<<( LayoutObject * ); };
Here is he implementation (for test purposes, I am only returning a QString containing the row and column number in data() ):
RailDocModel::RailDocModel( QObject * parent ) : QAbstractTableModel{ parent } {} int RailDocModel::columnCount( const QModelIndex & parent ) const { Q_UNUSED( parent ) return LayoutObject::nFields; } int RailDocModel::rowCount( const QModelIndex & parent ) const { Q_UNUSED( parent ) return Elements.count(); } QVariant RailDocModel::data( const QModelIndex & index, int role ) const { if (role == Qt::DisplayRole) return QString( "Row%1, Column%2" ) .arg( index.row() + 1 ) .arg( index.column() + 1 ); return QVariant(); } QVariant RailDocModel::headerData( int section, Qt::Orientation orientation, int role ) const { switch( role ) { case Qt::DisplayRole: return LayoutObject::GetHeader( section ); default: return QAbstractTableModel::headerData( section, orientation, role ); } } void RailDocModel::operator<<( LayoutObject * NewElement ) { Elements << NewElement; }
Here is MainWindow ():
MainWindow::MainWindow( QWidget *parent ) : QMainWindow( parent ), ListModel( new RailDocModel( this ) ), pDoc( new RailDoc( AppSettings, *ListModel ) ), ui( new Ui::MainWindow ) { int i; ui->setupUi( this ); statusBar()->showMessage( tr( "Ready" ) ); List = ui->centralwidget->findChild<QTableView*>( "ElementView" ); List->setModel( ListModel ); List->setSelectionBehavior( QAbstractItemView::SelectRows ); List->setSelectionMode( QAbstractItemView::SingleSelection ); List->horizontalHeader()->setDefaultAlignment( Qt::AlignLeft ); for( i = 0; i < LayoutObject::nFields; i++ ) List->setColumnWidth( i, LayoutObject::GetHeaderWidth( i ) ); List->setEditTriggers( QAbstractItemView::NoEditTriggers ); QObject::connect( statusBar(), &( statusBar()->messageChanged ), this, &OnStatusMessageChanged ); }
The lines that set the header text (in my model) and column width (in MainWindow()) work properly.
I figure I am blind to something simple that I am missing, but after a week of going over this and trying dozens of things, I hope someone can see what I don't.
-
Christian Ehrlicher Lifetime Qt Championreplied to Calvin H-C on last edited by Christian Ehrlicher
@Calvin-H-C said in QTableView with QAbstractTableModel derrived class not displaying data:
Elements
I don't see where you fill this container.
void RailDocModel::operator<<( LayoutObject * NewElement ) { Elements << NewElement; }
And here you're missing some important signals: https://doc.qt.io/qt-6/model-view-programming.html#inserting-and-removing-rows
-
@Christian-Ehrlicher said in QTableView with QAbstractTableModel derrived class not displaying data:
Elements
I don't see where you fill this container.
Sorry, I should have mentioned that Elements is being filled, and has been tested. I was originally using a QListView with QStringListModel which worked to show that Elements was being filled. When I switched to QTableView and QAbstractTableModel I had added a debug statement to rowCount() to also confirm that Elements was filled.
void RailDocModel::operator<<( LayoutObject * NewElement ) { Elements << NewElement; }
And here you're missing some important signals: https://doc.qt.io/qt-6/model-view-programming.html#inserting-and-removing-rows
That pointed me to what I was missing. Changing operator<<() to this was the solution:
void RailDocModel::operator<<( LayoutObject * NewElement ) { beginInsertRows( QModelIndex(), Elements.count(), Elements.count() ); Elements << NewElement; endInsertRows(); }
I had tried adding beginInsertRows() and endInsertRows() recently, but had used nullptr as the first parameter to beginInsertRows() instead of QModelIndex().
-