许多 QWidget 对象支持拖放活动。那些允许拖动的widget 必须用 setDragEnabled() 设置为 可拖拽。完后dragEnterEvent、 dropEvent等函数会在相应事件发生时候被回调。另一方面,该widget响应拖放事件时,事件里包含mimeData,mimeData 为拖拽文件数据提供了一个容器,存储了MIME 类型的拖拽文件的 信息。
下面时监听到的几种与拖拽相关的事件:
-
DragEnterEvent提供了一个事件,当拖动动作进入它时,该事件被发送到目标小部件。
-
DragMoveEvent在拖放操作正在进行时使用。
-
DragLeaveEvent在拖放操作离开小部件时生成。
-
另一方面,DropEvent发生在放置完成时。可以有条件地接受或拒绝事件的提议操作。
class DropArea(QLabel):
def __init__(self, *args, **kwargs):
super(DropArea, self).__init__(*args, **kwargs)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
print("drag event")
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
print("drop event")
files = list()
urls = [u for u in event.mimeData().urls()]
for url in urls:
print(url.path())
files.append(url.toLocalFile())
print(files)
我们定义了一个DropArea,而这个类继承自QLabel控件,同时我们在初始化的时候允许该控件接受拖放,然后我们定义了dragEnterEvent,该函数会在我们用鼠标拖动文件到该控件上时被触发,最后,我们定义了dropEvent,该函数会在鼠标拖动到上边以后,放开鼠标左键的时候被触发。而event.mimeData().urls()上则返回一个多个QUrl类型的实体,每一个QUrl中包含了每一个文件的路径,通过toLocalFile()可以获取到QUrl中包含的在当前系统上的全路径格式。
有了自定义的DropArea控件,我们通过程序动态的将该控件添加到横向Layout中。在Qt Creator的对象窗口中我们很容易的找到,横向Layout的对象名为horizontalLayout,然后使用horizontalLayout的addItem方法添加控件进去。
在MainWindow类的初始化函数最后添加如下代码,从而在主界面中添加拖放区
self.ui.dropArea = DropArea("或 拖动文件或文件夹到这里", self)
self.ui.horizontalLayout.addWidget(self.ui.dropArea)
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) # QtWidgets
self.ui.horizontalLayout.addItem(spacerItem)
运行代码我们的主窗口就可以支持拖放了