如果不是顶级小部件,如何接收dropEvent?

时间:2019-02-07 08:48:33

标签: qt pyqt5 pyside2

编辑:此问题似乎特定于Qt版本5.12.0。请参阅答案以获取更多详细信息和解决方法

我正在尝试实现将文件加载到应用程序中的放置区。 当我仅将小部件显示为顶级小部件时,它就可以工作,但是一旦将其包含到另一个父小部件中,它就会停止工作。

问题是,尽管我已经收到dragEnterEvent并接受了它,但我却从未见过dropEvent

这是我的小部件:

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())

这是我设法使其工作的方式:

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

这是一个示例,其中它不起作用(dragEnter可以正常打印两张照片,但是dropEvent却什么也不打印):

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

有什么坏事的线索吗?家长需要转发事件吗?如果是,该如何实施?

1 个答案:

答案 0 :(得分:1)

这似乎是Qt 5.12.0中引入的错误,并将在Qt 5.12.1中修复,请参见this discussion和此bug report

与此同时:

  

可以通过重新实现dragMoveEvent()并在那里接受事件来解决该问题。

即添加例如FileDropZone类的以下方法:

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