How to move up a row in QTableView?



  • I have a QTableView with 3 rows and 2 columns. I want to a move up/move down a Single Row when a Push Button is clicked? How can i move up/down a Row in QTableView ?



  • Try
    @QTableView::selectionModel()->select(const QModelIndex & index, QItemSelectionModel::SelectionFlags command);@

    from "here":http://qt-project.org/doc/qt-5.1/qtcore/qitemselectionmodel.html#select .

    In conjunction with "finding selected rows":http://qt-project.org/doc/qt-5.1/qtcore/qitemselectionmodel.html#selectedRows
    @QTableView::selectionModel()->selectedRows();@

    You should have a nice way to select things.

    And, if everything else fails, pack up a "QKeyEvent":http://qt-project.org/doc/qt-5.1/qtgui/qkeyevent.html, "send":http://qt-project.org/doc/qt-5.1/qtcore/qcoreapplication.html#postEvent it ("alternatively)":http://qt-project.org/doc/qt-5.1/qtcore/qcoreapplication.html#sendEvent and be done that way. Although I think that would be quite a strange solution.
    Maybe there is an even better one?

    I hope this helps. :)



  • Thanks thEClaw for your suggestion. Can u please post an example of it. Because i feel it is too complicated.



  • Too lazy to read the documentation? I put all the links in there, and for a good reason.
    But I will try to elaborate nonetheless:

    Connect your button to a slot, inside that slot do something like:
    @QTableView *table = this;//use your tableview instead!
    QModelIndexList rows = table->selectionModel()->selectedRows();
    if(rows.count())
    {
    //'-1' has to modified if you want to go downwards
    QModelIndex newRow = rows.first().model()->index(rows.first().row() - 1, rows.first().column());
    if(newRow.isValid())
    table->selectionModel()->select(newRow, QItemSelectionModel::ClearAndSelect);
    }@

    I don't think that's too pretty, but there have to be some drawbacks for not looking things up yourself, right?
    The formerly mentioned solution using events would look like this (again that's what to put into the slot):
    @QTableView *table = this;//use your tableview instead!
    QKeyEvent *e1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up);
    QKeyEvent *e2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Up);
    QCoreApplication::postEvent(table, e1);
    QCoreApplication::postEvent(table, e2);@

    The TableView should handle these correctly by default. This solution might be even uglier than the first one. Or not, depending on how you look at it.

    Not to forget, there is a function
    @QTableView::selectRow(int)@

    which might open up more elegant ways to select a row, but that path you should try to explore on your own.



  • Thanks for your code. The First code which u gave is for changing the selection, that moves up the selection. But i want to move up or move down the entire row (not the selection).

    [quote author="thEClaw" date="1378630106"]
    Connect your button to a slot, inside that slot do something like:
    @QTableView *table = this;//use your tableview instead!
    QModelIndexList rows = table->selectionModel()->selectedRows();
    if(rows.count())
    {
    //'-1' has to modified if you want to go downwards
    QModelIndex newRow = rows.first().model()->index(rows.first().row() - 1, rows.first().column());
    if(newRow.isValid())
    table->selectionModel()->select(newRow, QItemSelectionModel::ClearAndSelect);
    }@
    [/quote]

    From the second code using QEvents, How can you pass two arguments for a QKeyEvent. As far as i know, we cannot use two arguments for a QKeyEvent. That will throw us an error, "QKeyEvent " No Overloaded Function takes 2 arguments. (Please correct me if i am wrong).

    [quote]
    @QTableView *table = this;//use your tableview instead!
    QKeyEvent *e1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up);
    QKeyEvent *e2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Up);
    QCoreApplication::postEvent(table, e1);
    QCoreApplication::postEvent(table, e2);@
    [/quote]



  • "QKeyEvent constructor":http://qt-project.org/doc/qt-5.1/qtgui/qkeyevent.html#QKeyEvent

    If you want to actually move the row, you should ask the underlying source model (not the proxy model, if you are using one) to "remove a row":http://qt-project.org/doc/qt-5.1/qtgui/qstandarditemmodel.html#takeRow and "insert it somewhere else":http://qt-project.org/doc/qt-5.1/qtgui/qstandarditemmodel.html#insertRow
    If you are using a proxy model, this change might not result in what you would visually expect, however.

    Interchanging rows:
    @QTableView *table = this;//use your tableview instead!
    int row = 2;//somehow you have to pick a row to move
    int newRow = row - 1;//could be changed...
    QList<QStandardItem *> items = table->model()->takeRow(row);//for a QStandardItemModel
    if(newRow > row)
    newRow --;
    table->model()->insertRow(newRow, items);@

    Something like this, it isn't tested.
    You could instead switch the contents of the rows, by just iterating over all the columns and manually interchanging their content. This would even work if you were using a proxy model, at least visually. The underlying data would change depending on what your proxy model was currently doing (filtering, sorting, ...). So you have to know whether you want the actual data to change, or just their visual representation. And you should know what kind of model your tableview is working with (and if that model has a "submodel", a "QAbstractProxyModel::sourceModel()":http://qt-project.org/doc/qt-5.1/qtcore/qabstractproxymodel.html#sourceModel-prop ).



  • @
    Void MainWindow::MoveRow(bool moveUp)
    {
    QStandardItemModel *item = qobject_cast<QStandardItemModel *>(ui->tableView->model());
    int row = ui->tableView->currentIndex().row();
    if(moveUp && row == 0) // if the item is in first row
    {
    return;
    }
    int newRow = row-1;
    QList<QStandardItem *> list = item->takeRow(row) ;
    item->insertRow(newRow,list);
    }
    @

    And in your slot,

    @void MainWindow::on_PushButonClicked()
    {
    moveRow(true);
    }@

    Thats all.... Hope it Helps.. :-)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.