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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.