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

how to programmatically select new row in TableView when row is added to TableModel



  • I have a tableView subclass which I set up like this:

    auto *model = new QSortFilterProxyModel(parent);
    model->setSourceModel(myModel);
    model->setFilterKeyColumn(0);
    myTableView->setModel(model);
    

    selectionMode = SingleSelection
    selectionBehavior = SelectRows
    sortingEnabled = true

    My model is a subclass of QAbstractTableModel. I use this function (triggered by a menu item) to add data:

    void ActionModel::addAction (Action *act)
    {
        int newRow = actions.count();
        beginInsertRows(QModelIndex(), newRow, newRow);
        actions.append(act);
        endInsertRows();
    }
    

    This works perfectly. The new data shows up in my Table View and I can sort it by each column.
    I want to programmatically select the row for the new entry. I assume I should call:

    void QTableView::selectRow(int row);
    

    but because the View might be sorted, I don't know which row number to select.
    How do I find the row in the view that corresponds to the row in my model?


  • Lifetime Qt Champion

    Hi
    You mean to know its original index unsorted ?
    Maybe this does the trick ?
    http://doc.qt.io/qt-5/qsortfilterproxymodel.html#mapToSource



  • @mrjj Not exactly, I want to know the row number where the new data item is displayed. Actually I don't care where it is, I just want it selected, but the only interface I've found is QTableView::selectRow(int row)
    It looks like mapSelectionFromSource might work, but I don't know how to get a QItemSelection for the data in my model.



  • I found a solution that mostly works. When I add the new data to my model, I return a QModelIndex that I later pass to the QSortFilterProxyModel->mapFromSource () which gives me the QModelIndex of the matching item in the view. Then you have to use the tableView's selectionModel to select it.

    QModelIndex ActionModel::addAction (Action *act)
    {
        int newRow = actions.count();
        beginInsertRows(QModelIndex(), newRow, newRow);
        actions.append(act);
        endInsertRows();
    	return (index(newRow,0));
    }
    
    tableView->selectionModel()->select (proxy->mapFromSource (qmi), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
    

    This all works exactly as I want if I don't sort the table.
    If I add 2 rows, then sort the table and add a 3rd row, the second row added shows a light blue on only the first column.

    0_1526177896170_tableview.png

    See how the Baker field is rendered? It goes away when the window does not have focus. Any idea what it is or how to get rid of it?


  • Qt Champions 2019

    The light blue cell is the cell which has the current index.



  • Thanks, I changed:

    ui->actionListView->selectionModel()->select (proxy->mapFromSource (qmi), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
    

    to

    ui->actionListView->setCurrentIndex (proxy->mapFromSource (qmi));
    

    And now it is working as I expected. I didn't realize that the current index and the selection are 2 different things.


Log in to reply