Linked Questions

Popular Questions

How to receive dropEvent when not a top level widget?

Asked by At

Edit: this issue seems to be specific to Qt version 5.12.0. See the answers for more details and for a workaround

I'm trying to implement a drop zone for loading files into my application. It works when I just show the widget as a top level widget, but it stops working as soon as I include it into another parent widget.

The problem is, altough I'm receiving dragEnterEvent and accepting it, I never see the dropEvent.

This is my widget:

class FileDropZone(qt.QLabel):
    """Target area for a drag and drop operation"""
    height = 33

    def __init__(self, text="Add file", parent=None):
        super().__init__(text, parent)
        stylesheet = """
            QLabel {
                border: 2px dotted #B4BDBA;
                qproperty-alignment: AlignCenter;
            }
            """
        self.setStyleSheet(stylesheet)
        self.setAcceptDrops(True)
        self.setFixedHeight(self.height)

    def dragEnterEvent(self, event):
        print("in drag enter event")
        if event.mimeData().hasUrls():
            print("hasUrls()")
            event.acceptProposedAction()

    def dropEvent(self, event):
        print("in drop event")
        urls = event.mimeData().urls()
        for url in urls:
            print(url.isLocalFile(), url.toLocalFile())

This is how I manage to make it work:

app = qt.QApplication([])
a = FileDropZone()
a.show()
app.exec_()

And this is the example where it does not work (dragEnter works, both prints are properly printed, but dropEvent does not print anything):

app = qt.QApplication([])
a0 = qt.QWidget()
l = qt.QHBoxLayout(a0)
a1 = FileDropZone("drop here", a0)
l.addWidget(a1)
a0.show()
app.exec_()

Any clues about what is broken? Does the parent need to forward the event, and if so, how should I implement it?

Related Questions