Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Passing custom widget through drag&drop



  • Hi All,

    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.
    Sat



  • Hi @ShinSat

    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.

    -Michael.



  • @m.sue Thanks for an update!
    Is there any code snippet so that I can learn in practical codes?



  • Hi @ShinSat

    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.

    -Michael.



  • @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...
    +++++++++++++++++++++++++++++++++++++++++++++++++
    mime.setData('application/widget', QByteArray(QLabel('ABC')))
    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'
    ++++++++++++++++++++++++++++++++++++++

    Any ideas???


  • Lifetime Qt Champion

    Hi,

    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?

    Thanks,
    Sat


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    Give your widgets a proper interface that allows to retrieve their state so that you can restore them as needed.


Log in to reply