使用新值更新QTableView中的单元格

4

我是新手,正在学习使用Qt编程,我的英语不是很好。我的问题是,当我更新QTableView中的一个单元格以在另一个单元格中使用其值时,它使用的是先前的值而不是新值。以下是我正在编写的代码,请帮忙看一下,谢谢。

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;
}
3个回答

6
如果您正在使用自定义数据模型(可能是从 QAbstractTableModel 继承的,因为我们在讨论 QTableView),您可以通过发出QAbstractItemModel::dataChanged()信号来通知视图数据已更改。

这是我如何做到的。

更新整行:

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);

更新整个列,但仅限于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});

通过将UpdateRow(row)和UpdateColumn(column)等方便函数添加到您的项模型中,如果您在外部更改数据,则可以从模型本身外调用这些函数。
您不希望告诉视图更新自身 - 如果有多个视图查看同一模型怎么办?让模型通知所有附加的视图已更改。

1
这是我使用的代码,如果有人遇到同样的问题可以参考。
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));
    }
}

这将更新依赖于已更新的另一个单元格的单元格值。


0

这种方法似乎有几个不太好的地方:

  1. 如果您希望在不同的列中呈现相同的值,或者您有一个列取决于另一列的值,则应该相应地设计提供视图的模型。
  2. 您调用的setData是一个纯虚函数,在模型中实现。因此,您可能希望修改setData实现,而不是捕获Enter / Return键按下并对其进行操作。因为所有模型更改都通过此函数进行。不要忘记为更改的索引发出dataChanged信号。

非常感谢,我会按照您的指示使用dataChange信号。 - Ricky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接