Dragging QListWidgetItem into QGraphicScene and create QGraphicsItem
-
Hey.
I do have an object in my software which I have declared a
QMetaType
so I can store it in aQVariant
. Now I have aQListWidget
that shows all instances of this object with its value stored inside the individualQListWidgetItems
as UserType.Module module("Module A"); QListWidget* list = new QListWidget(); [...] QListWidgetItem* item = new QListWidgetItem(module.name()); item->setData(Qt::UserRole, QVariant::fromValue(module)); list->addItem(item);
Now I want to drag this item onto a
QGraphicsScene
and extract theQVariant
contained in theQListWidgetItem
inside theQGraphicsScene::dropEvent(...)
and create a new customQGraphicsItem
that is a graphical representation of the Module there, as well.I was reading in the Drag & Drop Framework documentation as well as the documentation for QGraphicsView but since the QListWidgetItem supports drag&drop by default, I was wondering if there isn't an easy way to get this done.
Any help is really appreciated!
-
@tobiSF
IIRC thats not cleanly possible withQListWidget
.the model needs to provide the drop-data and a mime-type you can listen to in the QGraphicsScene (see this). QListWidget / QStandardItemModel lacks such a possibility.
In the QGraphicsScene dropEvent handler you then can listen for your custom mime-type and read the drop-data (item-type, content,...) from the model. -
@raven-worx, I was afraid this was the answer. Which is too bad, when seemingly everything you'd need is in place on one side of the drag&drop operation and you would only need to access that information on the receiving end.
-
@tobiSF
it's not that bad. All you have to do is just implement a new model class. -
@raven-worx not bad in a hard/difficult way. More disappointing that there's no straightforward way. Thank you, anyway!
-
I did not test it but it looks like everything is already in Qt, just not documented.
void dropEvent(QGraphicsSceneDragDropEvent *event){ const QByteArray mimeData = event->mimeData()->data("application/x-qabstractitemmodeldatalist"); QDataStream mimeReader(mimeData); int row,col; QMap<int,QVariant> modelData; for(;;){ mimeReader.startTransaction(); mimeReader >> row >> col >> modelData; if(!mimeReader.commitTransaction()) break; const auto userRoleIter = modelData.constFind(Qt::UserRole); if(userRoleIter!=modelData.cend()) doSomethingWithModule(userRoleIter->value<Module>()); } }
-
@VRonin said in Dragging QListWidgetItem into QGraphicScene and create QGraphicsItem:
const QByteArray mimeData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QDataStream mimeReader(mimeData);
int row,col;
QMap<int,QVariant> modelData;
for(;;){
mimeReader.startTransaction();
mimeReader >> row >> col >> modelData;
if(!mimeReader.commitTransaction())
break;
const auto userRoleIter = modelData.constFind(Qt::UserRole);
if(userRoleIter!=modelData.cend())
doSomethingWithModule(userRoleIter->value<Module>());
}@VRonin, thank you very much. This works like a charm and does exactly what I was looking for.
-
@tobiSF
@VRonin
that's what i meant it's not "cleanly possible". I knew that some internal data was in the mime-data, but i believed that you need a reference to the model afterall, thus "not cleanly". But thats not the case.Sorry for not being more specific on this.
-
@raven-worx no worries, your help is appreciated and I think I understood you correctly.