How to drag & drop rows within QTableWidget



  • Hello all,
    I want to drag & drop rows in QTableWidget to change order of rows in the table.
    I want only move whole rows, not overwrite or delete.

    I've tried
    @
    table->setDragDropOverwriteMode(false);
    table->setDragEnabled(true);
    table->setDragDropMode(QAbstractItemView::InternalMove);
    item->setFlags(item->flags() & ~(Qt::ItemIsDropEnabled));
    @
    but it doesn't fully enable to move a row.

    My question is: is it possible to get requested behavior just by correct setting of some flags or is it necessary to inherit and re-implement something?
    Working example is appreciated.

    Thanks in advance,

    Jarda



  • The example below allows you to move rows by calling "setMovable(true)":http://doc.qt.nokia.com/4.7/qheaderview.html#setMovable on the header. Does it give you the behavior you want?

    @
    #include <QtGui>

    int main( int argc, char** argv ) {
    QApplication a( argc, argv );
    QTableWidget table(4,4);
    for(int row =0;row<4;row++)
    for(int col = 0;col<4;col++)
    {
    QTableWidgetItem *item = new QTableWidgetItem(QString("Row%1 Col%2").arg(row).arg(col));
    item->setFlags(item->flags() | Qt::ItemIsSelectable);
    table.setItem(row,col,item);
    }
    table.verticalHeader()->setMovable(true);
    table.show();
    return a.exec();
    }
    @



  • Thank you for reply. but I also need to change the number of moved row. When I drag the row number 5 to first row I also need it to become row number 1 and reorder the rest (not only the row number 5 displayed as first).



  • I'm not sure if that is possible within QTableWidget. If you do it with QTableView and a custom model, you would overwrite the drag / drop stuff in the model.



  • Thank You Gerolf for reply. Can you please give me a hint (or sample code) how to implement it with custom model?



  • If you look inside the "qt docs":http://doc.qt.nokia.com/4.7/model-view-programming.html there ios a chapter on model view and also on dnd with MVD. I propose you start reading there.



  • I wanted the same functionality for my app. So I searched through internet and didnt find anything. So I had to do it.

    So, you can do it with QTableWidget by using the cellEntered(int,int); then takeItem(row, col) and then setItem()...

    @connect(ui->tableWidget, SIGNAL(cellEntered(int,int)), this, SLOT(cellEnteredSlot(int,int)));@

    @void MainWindow::cellEnteredSlot(int row, int column){

        int colCount=ui->tableWidget->columnCount();
    
        int rowsel;
        
        if(ui->tableWidget->currentIndex().row()<row) rowsel=row-1; //down
    
        else if(ui->tableWidget->currentIndex().row()>row) rowsel=row+1; //up
    
        else return;
    
                QList<QTableWidgetItem*> rowItems,rowItems1;
                for (int col = 0; col < colCount; ++col)
                {
                        rowItems << ui->tableWidget->takeItem(row, col);
                        rowItems1 << ui->tableWidget->takeItem(rowsel, col);
    
                }
    
                for (int cola = 0; cola < colCount; ++cola)
                {
                        ui->tableWidget->setItem(rowsel, cola, rowItems.at(cola));
                        ui->tableWidget->setItem(row, cola, rowItems1.at(cola));
    
                }
    

    }@

    Warning: I think theres a bug.

    Although it works fine by clicking and holding the left mouse button and moving mouse up or down, it also works with Mouse WHEEL Scroll.

    I have not figure it out yet on how to check if mouse wheel was triggered so not to move selected row.

    The doc says:

    bq. This signal is only emitted when mouseTracking is turned on, or when a mouse button is pressed while moving into an item.

    BUT when you scroll the mouse wheel is not a mouse button press action.

    So I think its a BUG. Should I submit it?


Log in to reply
 

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