Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to resize newly added row in QTableView



  • Hello!
    I'm using QSqlRelationalTableModel with QTableView.
    Model is set to ManualSubmit:

    QSqlRelationalTableModel* model_log_;
    ...
    model_log_->setEditStrategy(QSqlTableModel::OnManualSubmit);
    

    Following code append new rows to model:

    QSqlRecord record_log = model_log_->record();
    record_log.setValue(0, time);
    record_log.setValue(1, message);
    model_log_->insertRecord(-1, record_log);
    model_log_->submitAll();
    

    Model's signal rowsInserted is connected to the function updateRows which is supposed to resize rows to their content:

    connect(model, &QSqlRelationalTableModel::rowsInserted,
                this, &MainWindow::updateRows);
    ...           
    void MainWindow::updateRows(const QModelIndex& parent, int first, int last)
    {
        ui->tableView_log->resizeRowsToContents();
    }
    

    So the issue is that the view does not resize newly added row. Only previous rows are affected. And it seems that the values of first and last arguments are 1 less from what the inserted row number should be.
    Same behavior is when connecting to model's dataChanged signal.

    Any help in correct implementation is appreciated.



  • @asc7uni

    hello, try with:

    ui->tableView_log->horizontalHeader()->setStretchLastSection(true);
    or
    ui->tableView_log->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    on the:

    ui->tableView_log->resizeRowsToContents();



  • Thank you for reply.

    What I need to change is rows size (vertical, height) not columns size (horizontal, width) so changing header properties doesn't help.

    StretchLastSection was already set, I just didn't show it in my code as irrelevant. Resize mode Stretch just made columns same size.

    I also tried to apply that properties to vertical header. It doesn't help either. Stetch last section does't change anything. Resize mode stretch made all rows same size.



  • @asc7uni

    Hi, while instead this here

    ui->tableView_log->resizeColumnsToContents();

    how do you straighten up?



  • @asc7uni

    So the issue is that the view does not resize newly added row. Only previous rows are affected.

    The way you describe it it's as though you're saying the new row has not been "properly" inserted (for the purpose of resizing) when the rowsInserted signal is emitted. If this were me and I were trying to find out what is going wrong, I'd temporarily make your slot call the resizeRowsToContents() on a single-shot QTimer with a short delay. Does the resizing then properly deal with the inserted row after the delay? If not, something else odd is at issue.



  • @JonB thanks for answer. You pointed me to right direction.
    I replaced

    void MainWindow::updateRows(const QModelIndex& parent, int first, int last)
    {
        ui->tableView_log->resizeRowsToContents();
    }
    

    with

    void MainWindow::updateRows(const QModelIndex& parent, int first, int last)
    {
        QTimer::singleShot(1000, ui->tableView_log, &QTableView::resizeRowsToContents);
    }
    

    And after short delay new row is resized to it's content. It even works with just 1ms delay.

    Long story short:
    I created minimal application to reproduce this. 1 second timer appends new rows. Model's rowsInserted connected to some local function which call View's resizeRowsToContents. Behaviour was same as before. Then I found that if this connection specified as QueuedConnection everything work as expeted.

    What I don't get is why it acts like this? Both emitting function and slot report same QThread. It seems I miss something basic.

    Here is pastebin link to code for everyone intrested: https://pastebin.com/a3C9srMP

    P.S. I will mark this as solved later but for now hope for some explanation.



  • @asc7uni
    Given that we have now proved it works after a delay. I don't know, this is a guess, but it might be that the resizing does not work till the new row has been shown, because something about that is required to determine the size. In your slot can you do some kind of .show() on the table view just before the resizeRowsToContents()? [There's no point asking me more about this, you'll have to try whatever you can find and see.]


Log in to reply