Question

I'm new, I'm learning to program in Qt and my English is not very good, my problem is that when I update a cell in a QTableView to use its value in another cell, it uses the previous value and not the new, I show them the code as I am doing, thanks.

bool MainWindow::eventFilter(QObject * watched, QEvent * event)
{
    if(event->type() == QEvent::KeyPress)
    {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        qDebug() << ke->type();
        if(ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return)
        {
            int fila = ui->tableView->currentIndex().row();
            int col = ui->tableView->currentIndex().column();
            double valor1 = ui->tableView->model()->data(ui->tableView->model()->index(fila,1)).toDouble();
            double valor2 = ui->tableView->model()->data(ui->tableView->model()->index(fila,3)).toDouble();
            if(col == 1 || col == 3)
            {
                ui->tableView->model()->setData(ui->tableView->model()->index(fila,col + 1),2.0*valor1);
                ui->tableView->model()->setData(ui->tableView->model()->index(fila,col + 3),200.0*valor1/valor2);
            }
        }
    }

return false;
}
Was it helpful?

Solution

This seems to be quite ditry approach to do this for several reasons:

  1. If you want the same value to be presented in different columns, or you have a column that depends on the value of another column, then you should probably design accordingly the model that feeds the view.
  2. setData that you are calling is a pure virtual function, that is implemented in the model. So instead of catching Enter/Return key presses and acting on them you might want to modify the setData implementation. Because this way of another all model changes pass through this function. Dont forget to emit dataChanged signals for the indexes that you change.

OTHER TIPS

If you are inside a custom data model, (perhaps inheriting from QAbstractTableModel, since we're discussing QTableViews), you can inform the view that a change of data has occurred by emitting the QAbstractItemModel::dataChanged() signal.

Here's how I do it.

Updating an entire row:

QModelIndex startOfRow = this->index(row, 0);
QModelIndex endOfRow   = this->index(row, Column::MaxColumns);

//Try to force the view(s) to redraw the entire row.
emit QAbstractItemModel::dataChanged(startOfRow, endOfRow);

Updating an entire column, but only the Qt::DecorationRole:

QModelIndex startOfColumn = this->index(0, mySpecificColumn);
QModelIndex endOfColumn = this->index(numRows, mySpecificColumn);

//Try to force the view(s) to redraw the column, by informing them that the DecorationRole data in that column has changed.
emit QAbstractItemModel::dataChanged(startOfColumn, endOfColumn, {Qt::DecorationRole});

By adding convenience functions like UpdateRow(row) and UpdateColumn(column) to your item model, you can call those functions from outside of the model itself, if you change the data externally.

You don't want to tell a view to update itself - what if there are more than one view looking at the same model? Let the model to inform all the attached views that it has changed.

This is the code that I use if anyone had the same problem.

connect(ui->tableView->model(),SIGNAL(dataChanged(QModelIndex,QModelIndex)),SLOT(UpdateData(QModelIndex,QModelIndex)));



void MainWindow::UpdateData(const QModelIndex & indexA, const QModelIndex & indexB)
{
    int col = indexA.column();
    int fila = indexA.row();

    if(col == 1 || col == 3)
    {
        double valor1 = ui->tableView->model()->data(ui->tableView->model()->index(fila,1)).toDouble();
        double valor2 = ui->tableView->model()->data(ui->tableView->model()->index(fila,3)).toDouble();
        ui->tableView->model()->setData(ui->tableView->model()->index(fila ,col + 1),2.0*valor1);
        ui->tableView->model()->setData(ui->tableView->model()->index(fila,col + 3),(200.0*valor1/valor2));
    }
}

This will update the cell value that depends on another cell that has been updated.

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