Unsolved 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, useitem->data(Qt::UserRole).toString()
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 reimplementedQListWidget::mimeData
function, I think you already implemented it in your previous post.protected: QMimeData* mimeData(const QList<QListWidgetItem*> items) const { QMimeData* mime= QListWidget::mimeData(items); QString text; for (QListWidgetItem* item : items) text.append(item->data(Qt::UserRole).toString()).append('\n'); mime->setText(text); 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 ?
-
Hi,
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 ??
-
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 reimplementdropEvent
, 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 { private: // map<QString, QString>::iterator it; public: using QListWidget::QListWidget; protected: 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; } else { md->setText(texts.join(QStringLiteral("\n"))); 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.protected: 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.