PyQt5使用mimeData实现拖拽事件教程示例解析下

 更新时间:2021年10月29日 00:00  点击:2414 作者:在逆境中蜕变

系列文章:
PyQt5使用mimeData实现拖拽事件教程示例解析上

实现思路

1、简要介绍QMimeData
2、QMimeData的用例1:在QT实现外部文件拖拽并展示
3、QMimeData的用例2:两个QListWidget之间的item交换
两个用例的实现效果如下:

在这里插入图片描述

在这里插入图片描述

1、简要介绍QMimeData

关于拖拽事件与QMimeData的一些关系,在第一篇文章中已经说明清楚了,这篇文章主要是往QMimeData中存放一些数据,以供拖动及放置的时候做判断(及数据通过QMimeData传递)
在第一个例子中: 由于文件的拖拽本身就存放了一些信息,因此我们并没有如第一篇文章那样创建一个QDrag,并且创建一个QMimeData
在第二个例子中: 我们此时给mimeData设置了一个text值,用于之后交换ItemList

2、QMimeData的用例1

在QT实现外部文件拖拽并展示

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtCore import QIODevice, QFile
class ComplexDrag(QMainWindow):
    def __init__(self):
        super(ComplexDrag, self).__init__()
        self.setAcceptDrops(True)
        self.textEditor = None
        self.initUI()
    def initUI(self):
        self.textEditor = QTextEdit()
        self.setCentralWidget(self.textEditor)
        self.textEditor.setAcceptDrops(False)
        self.setAcceptDrops(True)
        self.setWindowTitle("拖拽")
    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat("text/uri-list"):
        	# 关于这个函数和accept的区别在下面会展示
            event.acceptProposedAction()
    def dropEvent(self, event):
        urls = event.mimeData().urls()
        if urls == "":
            return
        fileName = urls.pop().toLocalFile()
        if fileName == "":
            return
        if self.readFile(fileName):
            self.setWindowTitle("Drag File Success")
    def readFile(self, fileName):
        r = False
        file = QFile(fileName)
        content = ""
        if file.open(QIODevice.ReadOnly):
            content = file.readAll()
            r = True
        self.textEditor.setText(str(content, "utf-8"))
        return r
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ComplexDrag()
    ex.show()
    app.exec_()

上述代码可以将外部的文件拖进来并进行展示,其中有几个要点要注意一下:

1、我们并没有创建QDrag事件,因为拖拽的起始并非在该窗口及窗口内的Widget中,而是从外部直接拖拽进来,这类事件本身已经有QDrag了

2、我们利用QMimeData中携带的信息判断进入的拖拽事件是否为我们所需要的,即event.mimeData().hasFormat(“text/uri-list”), 关于里面的类型,可以自行查找该网站Media Types

3、上面我们没有使用 event.accept 而是使用 acceptProposedAction 的原因如下图

在这里插入图片描述

4、拖放结束后,我们将文件读取进来并进行展示

3、QMimeData的用例2

两个QListWidget之间的item交换

# -*- coding: utf-8 -*-
import sys
from threading import Event
from PyQt5.QtGui import QDrag, QPixmap
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QListWidget, QDialog
from PyQt5.QtCore import QMimeData, Qt
class MainWindow(QDialog):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.projectA = ComplexDrag(self)
        self.projectB = ComplexDrag(self)
        self.projectA.addItem("Giosue Carducci")
        self.projectA.addItem("Eyvind Johnson")
        self.projectA.addItem("Sally Prudhomme")
        self.projectA.addItem("Henryk Sienkiewicz")
        self.projectA.addItem("Carl Spitteler")
        self.projectA.addItem("Rabindranath Tagore")
        self.projectA.addItem("Kawabata Yasunari")
        self.projectB.addItem("Rudolf Eucken")
        self.projectB.addItem("Anatole France")
        self.projectB.addItem("Rudyard Kipling")
        self.projectB.addItem("Thomas Mann")
        self.projectB.addItem("Eugene O'Neill")
        self.projectB.addItem("Sigrid Undset")
        lay = QHBoxLayout()
        lay.addWidget(self.projectA)
        lay.addWidget(self.projectB)
        self.setLayout(lay)
class ComplexDrag(QListWidget):
    onDropEvent = Event()
    def __init__(self, parent=None):
        super(ComplexDrag, self).__init__(parent)
        self.setAcceptDrops(True)
        self.startPos = None
    def removeSel(self):
        listItems = self.selectedItems()
        if not listItems:
            return
        for item in listItems:
            self.takeItem(self.row(item))
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.startPos = event.pos()
        super(ComplexDrag, self).mousePressEvent(event)
    def mouseMoveEvent(self, event):
        distance = (event.pos() - self.startPos).manhattanLength()
        if distance >= QApplication.startDragDistance():
            item = self.currentItem()
            if item:
                mimeData = QMimeData()
                mimeData.setText(item.text())
                drag = QDrag(self)
                drag.setMimeData(mimeData)
                pixmap = QPixmap("computer.svg").scaled(20, 20, Qt.KeepAspectRatio)
                drag.setPixmap(pixmap)
                self.removeItemWidget(item)
                if drag.exec(Qt.MoveAction) == Qt.MoveAction:
                    self.removeSel()
        super(ComplexDrag, self).mouseMoveEvent(event)
    def dragMoveEvent(self, event):
        source = event.source()
        if source and source != self:
            event.setDropAction(Qt.MoveAction)
    def dragEnterEvent(self, event):
        source = event.source()
        if source and source != self:
            event.setDropAction(Qt.MoveAction)
            event.accept()
    def dropEvent(self, event):
        source = event.source()
        if source and source != self:
            self.addItem(event.mimeData().text())
            event.setDropAction(Qt.MoveAction)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    app.exec_()

简要说明一下上面的实现过程:
1、我们在一个QWidget里面放置了两个QListWidget,并实现QListWidget之间item的交换

2、QListWidget中在mouseMoveEvent中创建了QDrag,并且我们创建一个QMimeData, 并在其存储当前选中item的text ,此处我们还设置了拖拽时候的图标样式(上面gif的是没有调整过大小的,实际效果可以把代码拿去自己运行一下)

3、在dragMoveEvent中判断是否为同源事件,非同源则将当前的拖拽设置为Qt.MoveAction

4、在dragEnterEvent中接收符合条件的拖拽事件

5、在dropEvent中,从QMimeData中获取最初设置的text值,并添加到当前的QListWidget,要注意的是,这里的self并非最初QDrag产生信号的self,两个self在这里其实代表的分别是两个窗口

6、在上一篇文章中 说过,exec方法是阻塞方法 ,因此在整个拖拽事件运行完之后,又会回到下面这段代码中,把后面的方法执行完,此时我们删去自身被拖动的item

if drag.exec(Qt.MoveAction) == Qt.MoveAction:
   self.removeSel()

以上就是PyQt5使用mimeData实现拖拽事件教程示例解析下的详细内容,更多关于PyQt5拖拽事件mimeData使用的资料请关注猪先飞其它相关文章!

原文出处:https://blog.csdn.net/weixin_40301728/article/details/113285

[!--infotagslink--]

相关文章

  • pyqt5 textEdit、lineEdit操作的示例代码

    这篇文章主要介绍了pyqt5 textEdit、lineEdit操作的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-12
  • PyQt5结合matplotlib绘图的实现示例

    这篇文章主要介绍了PyQt5结合matplotlib绘图的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-15
  • python编程PyQt5创建按钮及触发点击事件示例解析

    这篇文章主要为大家介绍了python编程使用PyQt5如何创建按钮及触发点击事件的示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步...2021-10-29
  • Pyqt5 实现窗口缩放,控件在窗口内自动伸缩的操作

    这篇文章主要介绍了Pyqt5 实现窗口缩放,控件在窗口内自动伸缩的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • PyQt5-QDateEdit的简单使用操作

    这篇文章主要介绍了PyQt5-QDateEdit的简单使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-12
  • PyQt5实现多张图片显示并滚动

    最近要做个网页图片批量下载工具,然后需要一个页面显示网页上的所有图片供用户勾选,再根据勾选的内容来下载指定图片,其中就涉及到要到同时显示多张图片,本文就来介绍一下...2021-06-11
  • PyQt5 实现给无边框widget窗口添加背景图片

    这篇文章主要介绍了PyQt5 实现给无边框widget窗口添加背景图片的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • pyqt5打包成exe可执行文件的方法

    最近做了一个窗口程序,那么能不能将其生成一个可执行文件,本文就介绍一下pyqt5打包成exe可执行文件的方法,感兴趣的可以了解一下...2021-05-15
  • 详解PyQt5中textBrowser显示print语句输出的简单方法

    这篇文章主要介绍了详解PyQt5中textBrowser显示print语句输出的简单方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-07
  • PyQt5使用mimeData实现拖拽事件教程示例解析下

    这篇文章主要为大家介绍了PyQt5使用mimeData实现拖拽事件的教程示例解析,系列文章详见文中跳转链接,有需要的朋友可以借鉴参考下,希望能够有所帮助...2021-10-29
  • PyQt5 显示超清高分辨率图片的方法

    这篇文章主要介绍了PyQt5 显示超清高分辨率图片的方法,帮助大家更好的理解和阿学习使用pyqt5,感兴趣的朋友可以了解下...2021-04-10
  • Pycharm配置PyQt5环境的教程

    这篇文章主要介绍了Pycharm配置PyQt5环境的教程,本文通过图文实例详解给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-10
  • Python3中PyQt5简单实现文件打开及保存

    本文将结合实例代码,介绍Python3中PyQt5简单实现文件打开及保存,具有一定的参考价值,需要的朋友们下面随着小编来一起学习学习吧...2021-06-10
  • 解决PyQt5 无边框后窗口的移动问题

    这篇文章主要介绍了解决PyQt5 无边框后窗口的移动问题,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧...2021-03-09
  • Python+PyQt5实现灭霸响指功能

    这篇文章主要介绍了Python+PyQt5实现灭霸响指功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-25
  • PyQt5多线程防卡死和多窗口用法的实现

    这篇文章主要介绍了PyQt5多线程防卡死和多窗口用法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-15
  • pyqt5中动画的使用详解

    这篇文章主要介绍了pyqt5中动画的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-10
  • Python深度学习实战PyQt5信号与槽的连接

    本文讲解信号与槽的连接机制,详细示范各种类型的信号/槽连接的实现方法,这是图形用户界面的核心内容。还将介绍面向对象的程序设计,这是图形用户界面的基本思想...2021-10-18
  • 详解PyQt5 GUI 接收UDP数据并动态绘图的过程(多线程间信号传递)

    这篇文章主要介绍了PyQt5 GUI 接收UDP数据并动态绘图(多线程间信号传递),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
  • PyQt 5 设置Logo图标和Title标题的操作

    这篇文章主要介绍了PyQt 5 设置Logo图标和Title标题的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09