Drag and Drop different item text in two QListWidgets

  • I have two QListWidgets , one named “Commands” on the left side and other named “XML Script” on the right side , I am able to drag and drop items from one List to another, How ever, when I drag one item, I don’t want drop that same item text, I want some changed text to be dropped.

    Example: In this example when I dragged “SetScroll Command” from “commands” QListWidget and I am trying to drop this in “XML Script” QListWidget , I need some different text to be dropped like If I drag ‘Pause Command’ from “Commands”, the dropped item in “XML Script ”should have item with text like “This is a Pause Command”

    ?? How can I achieve this, I am intending to keep a Map data structure which will have key as “Pause Command” and Value as “This is a Pause Command”. Whenever key text is dragged , value text shall be dropped,

    Any help appreciated.

  • You can add user data to QListWidgetItem

    QListWidgetItem *item = new QListWidgetItem("Pause Command");
    item->setData(Qt::UserRole, QString("This is a Pause Command"));

    And in the mimeData function which you has reimplemented, use


    instead of item->text()
    *Note: If you want to drop different text to different text editers, then this won't work.

    You can even define more user roles to store different datas

    #define MIME_TEXT_ROLE Qt::UserRole + 1
    #define MIME_HTML_ROLE Qt::UserRole + 2

  • Can you please code the mimeData Function ??

  • @Mr-Workalot
    It's just the reimplemented QListWidget::mimeData function, I think you already implemented it in your previous post.

        QMimeData* mimeData(const QList<QListWidgetItem*> items) const
            QMimeData* mime= QListWidget::mimeData(items);
            QString text;
            for (QListWidgetItem* item : items)
            return mime;

  • @Bonnie i tried the above mimeData function , when i drag from one QListWIdget to another QListWidget, it only transfers "Pause Command" and not its data i.e"This is a Pause Command",

    However, when i drag from QListWidget to QTextEdit , after dragging it shows "This is a Pause Command".

  • No need to reimplement QListWidget::mimeData. See https://forum.qt.io/post/444126

  • @VRonin Thanks for this, i got slight hope that my problem is solvable , but still kind of helpless here, in my case i want to drag item from one QListWidget-1 to QListWidget-2 but after dragging the text of that item in List widget -2 should change.

    How can i acheive this ? , can you please provide code for Drop EVent ?

  • Lifetime Qt Champion


    You have the code in the link @VRonin provided.

  • @SGaist Okay, But in my case this function does not gets executed, so, before

    void MainWindow::dropEvent(QDropEvent* event) 

    gets invoked , do i need to enter any other function ??

  • Lifetime Qt Champion

    Why are you implementing that method for your MainWindow ?

  • @Mr-Workalot
    Oh, sorry, I was misunderstanding your need, thinking you need to drop the text to a text edit.
    If you reimplement dropEvent, I think you should create a new class for listwidget-2 and reimplement there.

  • @SGaist Yeah, that's what, it kind of felt wrong to me, the place from where i am dragging is a modified QListWIdget,

    std::map<QString, QString> commands;
    bool first_time = true;
    class ListWidget : public QListWidget {
       //  map<QString, QString>::iterator it;
       using QListWidget::QListWidget; 
       QMimeData* mimeData(const QList<QListWidgetItem*> items) const
           QMimeData* md = QListWidget::mimeData(items);
           QStringList texts;
           for (QListWidgetItem* item : selectedItems())
             auto it = commands.find(item->text());
              texts << it->second;
           if (first_time == true)
               QString end = "</Script>";
               md->setText("<?xml version=\"1.0\" encoding=\"utf - 8\"?> \n <Script> \n"  + texts.join(QStringLiteral("\n")));
               first_time = false;
               return md;
               return md;

    and where i am dropping is a normal QListWidget,

    should , i create a DropEvent for where i am dropping, right ??

    and how do i create that , im very new to QT ?

  • @Bonnie said in Drag and Drop different item text in two QListWidgets:

    If you reimplement dropEvent, I think you should create a new class for listwidget-2 and reimplement there.

    oh okay, thanks for clarifying. and how can i reimpliment drop event for listwidget-2 ??
    what are the steps ??
    , i know im asking too much but if you help me once, im gonna learn this for life.

  • @Mr-Workalot
    Hmm..I tried to find an easiest way to handle this...
    The QDataStream decode/encode thing may need to subclass the model, too.
    So I think you just let it drop in the normal way, and then change it.

        bool dropMimeData(int index, const QMimeData *data, Qt::DropAction action)
            if(QListWidget::dropMimeData(index, data, action)) {
                if(QListWidgetItem *dropped = item(index)) {
                    dropped->setData(Qt::DisplayRole, dropped->data(Qt::UserRole));
                return true;
            return false;

    This is only working when you'll only accept drops from a item which you need to change its text to its Qt::UserRole.
    If you want to accept drops from other items, you may need to add some conditional statements.

Log in to reply