Passing custom widget through drag&drop
I have a quick question about QMimeData() in PyQt5.9.
Is it possible to pass a custom widget like a custom QLabel/QPushButton in QMimeData through Drag&Drop? How can I setData() the widget information? Also it would be great if there's any alternative if not possible.
I want to lay out the widget in different View(eg.Widget/QMainWindow).
Thanks in advance for your update.
If you just want to do it between different instances of your own program you can always serialize the object you want to drag, and de-serialize it at the drop. Which means you just send a string.
@m.sue Thanks for an update!
Is there any code snippet so that I can learn in practical codes?
In this example http://doc.qt.io/qt-5/qtwidgets-draganddrop-draggabletext-dragwidget-cpp.html you can see, they send text but do infact something with widgets.
@m.sue I'm trying it in Python but no luck so far..
mime = QMimeData() mime.setData('application/widget', QByteArray(QLabel('ABC')))
Got the following errors. SO,,, there should be a trick that I'm missing...
TypeError: arguments did not match any overloaded call:
QByteArray(): too many arguments
QByteArray(int, str): argument 1 has unexpected type 'QLabel'
QByteArray(Union[QByteArray, bytes, bytearray]): argument 1 has unexpected type 'QLabel'
In addition, tried this.
mime = QMimeData() itemData = QByteArray() dataStream = QDataStream(itemData) wgt = QWidget() dataStream << wgt mime.setData('application/widget', itemData)
and got the followings.
Traceback (most recent call last):
File "/Users/kiaora/pyqt/dragAndDrop/examples/draganddrop_test.pyw", line 230, in mousePressEvent
dataStream << wgt
TypeError: unsupported operand type(s) for <<: 'QDataStream' and 'QWidget'
You can't pass around widget instances though QMimeData. You should rather serialise the properties you want from your widget and create a new one based on that at the target location. Otherwise, you can always try to implement a custom QMimeData class that does handle QWidget objects.
Thank you very much for your help, @SGaist!
Well, based on the discussion so far, a right way is either to create a custom QMimeData class or, I guess, place and hierarchically handle all widget on ONE mother base widget, which would enable to re-lay out them according to the requirement(s). But not easy, right?
No, like also suggested, you can serialise the properties of your widget, create a new one on the target that you setup with said properties and then delete the original.
@SGaist The problem is the passing widget is a GUI with a lot of user inputs and app outputs ,not empty. You mean, I can copy and pass everything to reproduce it in the destination?
Give your widgets a proper interface that allows to retrieve their state so that you can restore them as needed.