Reimplementing drag and drop in a listwidget



  • Hi there!
    I'm trying to reimplement the drag and drop function of a listwidget so as to make it accept move actions between when moving its items around itself, and copy actions when dropping items from a treewidget.

    If I accept drops to my listwidget, enable drag and dropping and alter the default action from copy to move, like this (on the constructor of my listwidget):
    @
    this->setAcceptDrops(true);
    this->setDragDropMode(QAbstractItemView::DragDrop);
    this->setDefaultDropAction(Qt::MoveAction);
    @

    it works exactly as I want as for moving the listwidget items around itself. But I need to reimplement the following functions, also:
    @
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *e);
    void dropEvent(QDropEvent *event);
    void dragEnterEvent(QDragEnterEvent *event);
    @
    so as to make it accept both actions from itself and from the treewidget. Is there any way to just 'extend' the functionality and make it, at the dragEnterEvent to accept the TreeWidget items as copyaction as well?

    I find it quite rough to start the whole reimplementation, think that when I started reimplementing mousePressEvent the items in my listwidget stopped having the ability to be selected (because, apparently, on the default mousePressEvent they were selected and in my implementation they were not).

    So, I basically need to keep the default functionality as for moves inside the listwidget and to reimplement it only if the dragged object is of the treewidget*.

    *I know that I can call these in my treewidget:
    @
    this->setDragDropMode(QAbstractItemView::DragDrop);
    this->setDefaultDropAction(Qt::CopyAction);
    @
    and it works out of the box when dragging items from the treewidget to the listwidget, but I need to take further action after the drop event takes place, depending on the text that is being carried by the dropped item. So, I have to reimplement the DropEvent in the listwidget (and only this), but I don't want to reimplement the internal move of the listwidget items, that works fine out of the box.

    Thanks in advance for any help :)



  • I guess very few are working on dragging and dropping area. Even I also have many a questions on the same like how to develop these functions.. but I didn't find even a single proper thread. I want to link the items (linkaction)...



  • Reimplementing these functions might seem daring, but you don't need to write much code. I suggest taking a look at the "Draggable Icons Example":http://qt-project.org/doc/qt-4.8/draganddrop-draggableicons.html, which should come close to what you are doing.

    Most important part when tinkering with the guts of a Qt class is to always know when to call the base class implementation, and only filter out the events you really want to handle. In your case I suggest either using a QTimer to make sure that the mouse button has been pressed for a while and the user wants to initiate a drag & drop operation, or use a minimum distance the mouse has to be moved while holding down a mouse button. More on that should be found in the "examples section for drag and drop operations":http://qt-project.org/doc/qt-4.8/examples-draganddrop.html



  • I don't know if it's going to be of any help but I suggest doing something like this :
    @void ListW::dropEvent(QDropEvent * event){
    if(event->source()==this) // Test if it is an internal move
    {
    // If you want to link items (although i have no idea if it'll work) : event->setDropAction(Qt::LinkAction);
    event->accept();
    }
    else
    {
    //Process the incoming data
    event->acceptProposedAction();
    }
    }@

    I'm not sure the comparison will work this way but I reckon it should work if you cast event->source() to QListWidget.

    Voila! I hope it will help you.


Log in to reply
 

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