Question

I have a QTableView, which uses a model derived from QAbstractTableModel.

The model starts out with a number of rows and displays the data properly.

The model also has a timer attached to it, which upon expiring, gets the number of rows and columns, constructs an index for it, and emits dataChanged signal, to update the dynamic contents of the table.

The problem is when the number of rows it is supposed to display, changes.

In that case, even though I obtain a new index with the changed no. of rows, and update the table, it still doesn't display any new rows.

I've identified why, perhaps. Let's say I have 2 rows in the beginning, and next, 5 rows are supposed to be displayed. In the timer expiration logic, I've asked it to construct a new index, with new row count… but dataChanged() signal, will only change the data for the rows which had already been inserted in the first. The new rows are not displayed.

This is my code for the model.

TableLayout::TableLayout()
  : QAbstractTableModel()
{
  rowCount();
  columnCount();
  timer = new QTimer(this);
  timer->setInterval(3000);
  timer->start();
  connect(timer, SIGNAL(timeout()), this, SLOT(timerHit()));

  //ItemList[0].SetFields("Blah" ,"Blah" , "Blah" , "Blah" , "Blah", "Blah", true  );
  //ItemList[1].SetFields("Blah1" ,"Blah1" ,"Blah1" ,"Blah1" ,"Blah1", "Blah1", true );
}

void TableLayout::timerHit()
{
  int row = this->rowCount();
  qDebug() << "RowCOunt::" << row;
  qDebug() << " Now IT IS : " << row;
  int col = this->columnCount();
  qDebug() << "ColumnCOunt::" << col;
  QModelIndex Ind = createIndex( 0, 0);
  QModelIndex Ind1 = createIndex( row, col);
  data(Ind1);
  emit dataChanged(Ind, Ind1);
}

int TableLayout::rowCount(const QModelIndex& /*parent*/) const
{
  RtdbReader* rtdbReader = RtdbReader::instance();
  if (isConnected)
    return rtdbReader->Get_Number_of_Items();
  else return 2;
}

int TableLayout::columnCount(const QModelIndex& /*parent*/) const
{
  return 6;
}

QVariant TableLayout::data(const QModelIndex& index, int role) const
{
  int row = index.row();
  int col = index.column();

  //return row;
  int row_count, col_count = 0;
  if ( role == Qt::DisplayRole) {

    if ( col == 1)
      return ItemList[row]->GetExplanation();
    if ( col == 2) {
      qDebug() << " Now printing Sig name for row" << index.row();
      return ItemList[row]->GetCond_Sig_Name();
    }
    if ( col == 3)
      return ItemList[row]->GetDescription();
    if ( col == 5)
      return ItemList[row]->GetLogic();
    if ( col == 4)
      return ItemList[row]->Get_State_Text();
  } else if ( role == Qt::DecorationRole && col == 0 ) {
    bool col_to_display = ItemList[row]->GetValueColour();
    qDebug() << "colour in view:" << col_to_display;
    if  ( col_to_display ) {
      QString path = "Green.png";
      //QPixmap p( s_type1Icon );
      // return s_type1Icon;

      QIcon icon ( path );
      return icon;
    } else {
      QString path = "Yellow.png";
      //QPixmap p( s_type1Icon );
      // return s_type1Icon;

      QIcon icon ( path );
      return icon;
    }
  }

  if (role == Qt::TextAlignmentRole )
    return Qt::AlignCenter | Qt::AlignVCenter;

  /* else if ( role == Qt::BackgroundRole)
   {
     QBrush yellowBackground(Qt::yellow);
              return yellowBackground;
   }*/

  return QVariant();
}

Please suggest how I can change the view so new rows are added.

Thanks.

Was it helpful?

Solution

Just because you create a QModelIndex to the element at row, col, doesn't mean you created data for that element (and also not for the elements between the current end and that element).

You have to use setData(...) to add new data to the table, and then emit dataChanged(...) for the view to display it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top