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
Forum Updated to NodeBB v4.3 + New Features

QTableView with QAbstractTableModel derrived class not displaying data

Scheduled Pinned Locked Moved Solved General and Desktop
qtableview
3 Posts 2 Posters 366 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 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.

    Christian EhrlicherC 1 Reply Last reply
    0
    • C Calvin H-C

      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 EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 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
      2
      • Christian EhrlicherC 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

        C Offline
        C Offline
        Calvin H-C
        wrote on 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

        • Login

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