Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableView with QAbstractTableModel derrived class not displaying data
QtWS25 Last Chance

QTableView with QAbstractTableModel derrived class not displaying data

Scheduled Pinned Locked Moved Solved General and Desktop
qtableview
3 Posts 2 Posters 301 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Calvin H-C
    wrote on 24 Dec 2023, 01:08 last edited by
    #1

    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.

    C 1 Reply Last reply 24 Dec 2023, 07:50
    0
    • C Calvin H-C
      24 Dec 2023, 01:08

      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.

      C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 24 Dec 2023, 07:50 last edited by Christian Ehrlicher
      #2

      @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

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      C 1 Reply Last reply 24 Dec 2023, 14:09
      2
      • C Christian Ehrlicher
        24 Dec 2023, 07:50

        @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

        C Offline
        C Offline
        Calvin H-C
        wrote on 24 Dec 2023, 14:09 last edited by
        #3

        @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().

        1 Reply Last reply
        0
        • C Calvin H-C has marked this topic as solved on 24 Dec 2023, 14:09

        2/3

        24 Dec 2023, 07:50

        • Login

        • Login or register to search.
        2 out of 3
        • First post
          2/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved