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

目录
  • 实现思路
  • 1、简要介绍QMimeData
  • 2、QMimeData的用例1
    • 在QT实现外部文件拖拽并展示
  • 3、QMimeData的用例2
    • 两个QListWidget之间的item交换

系列文章:
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使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • PyQt5每天必学之拖放事件

    在PyQt5教程的这一部分,我们将讨论拖放操作. 在电脑图形用户界面,拖放事件就是点击一个虚拟对象,并将其拖动到其他位置或到另一个虚拟物体的动作.在一般情况下,它可以被用于调用多种动作,或创建两个抽象对象之间的关联的各种类型. 拖放事件是图形用户界面的一部分.拖放操作使用户能够直观地操作一些复杂的事情. 通常情况下,我们可以拖放两种类型:数据或某些图形对象.如果我们从一个应用程序拖动图像到另一个,我们拖放的是二进制数据.如果我们拖放Firefox标签并将其移动到另一个地方,我们拖放的是图形组件.

  • python3+PyQt5重新实现自定义数据拖放处理

    本文分成两部分,第一部分通过python3+PyQt5实现自定义数据的拖放操作.第二部分则对第一部分的程序进行修改,增加拖放操作时,菜单提示是否移动或拷贝,还有可以通过ctrl键盘来设置移动过程中拷贝源而非会将源删除. 自定义数据MIME数据类型QMimeData,MIME是一种用于处理具有多个组成部分的自定义数据的标准化格式.MIME数据由一个数据类型和一个子类型构成–例如,text/plain,text/html,image/png,要处理自定义MIME数据,就必须要选用一种自定义数据类型和

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

    目录 实现思路 1.简要介绍QMimeData 一.QDrag 二.drag相关事件 三.dropEvent 四.拖放关键逻辑图 2.QMimeData的用例1 在QT实现输入框的文字拖拽 3.QMimeData的用例2 在QT实现按钮拖动 实现思路 1.简要介绍QMimeData 2.QMimeData的用例1:在QT实现输入框的文字拖拽 3.QMimeData的用例2:在QT实现按钮拖动 两个用例的实现效果如下: 用例1: 用例2: 1.简要介绍QMimeData 一.QDrag 首先是创建

  • python GUI库图形界面开发之PyQt5拖放控件实例详解

    本篇,我们学习PyQt5界面中拖放(Drag 和Drop)控件. 拖放动作 在GUI中,拖放指的是点击一个对象,并将其拖动到另一个对象上的动作.比如百度云PC客户端支持的拖放文件以快速移动文件: 拖放动作能够很直观很方便的在GUI程序中完成一些很复杂或繁琐的操作. 在PyQt中实现拖放 在PyQt5中,我们也可以很轻松地使用拖放功能. 使用Qt设计师或者使用API都可以实现.我们先使用Qt设计师将GUI的图形设计出来,在之前的GUI的基础上,我们新建一个选项卡. 我们新建了一个选项卡,然后在里面

  • PyQt5实现拖放功能

    在这节教程中,我们将探讨PyQt5中的拖放操作. 在计算机图形用户界面(GUI)中,拖放是在某个虚拟对象上点击并拖动到另一个位置或虚拟对象上的操作.它通常用于调用多个动作,或为两个抽象对象创建某些联系. 拖放是图形用户界面的一部分.拖放可以使用户直观地完成某些复杂的操作. 通常我们可以对两种事物进行拖放操作:数据或某些图形对象.如果我们将某个应用中的图片拖放到另一个应用,我们拖放的是二进制数据.如果将Firefox的某个标签页拖放到其他地方,我们拖放的是一个图形组件. 简单的拖放 在第一个示例中

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

    目录 实现思路 1.简要介绍QMimeData 2.QMimeData的用例1 在QT实现外部文件拖拽并展示 3.QMimeData的用例2 两个QListWidget之间的item交换 系列文章: PyQt5使用mimeData实现拖拽事件教程示例解析上 实现思路 1.简要介绍QMimeData 2.QMimeData的用例1:在QT实现外部文件拖拽并展示 3.QMimeData的用例2:两个QListWidget之间的item交换 两个用例的实现效果如下: 1.简要介绍QMimeData 关

  • 使用javaScript实现鼠标拖拽事件

    本文实例为大家分享了js实现鼠标拖拽事件的具体代码,供大家参考,具体内容如下 <html> <head> <meta charset="UTF-8"> <title></title> <style> body{ margin: 0; padding: 0; } div{ position: absolute; top: 200px;/*div的y轴*/ left: 150px;/*div的x轴*/ width: 3

  • IE8利用自带的setCapture和releaseCapture解决iframe的拖拽事件方法

    最近有个需求须要实现左右拖拽功能,页面右边是个iframe页面,在chrome测试通过之后,发现在ie8上面效果不是很理想,最后查找资料得知可以使用ie自带的setCapture和releaseCapture来解决. sideDragBar.on('mousedown.sideMenu', function(e){ this.setCapture && this.setCapture();// ie下可以使用setCapture来解决object拖拽问题 startDragging(e);

  • javascript实现文件拖拽事件

    本文实例为大家分享了javascript实现文件拖拽事件的具体代码,供大家参考,具体内容如下 1.效果图: 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <style type="text/css"> #div1 { width: 350px; height: 70px; pa

  • JavaScript鼠标拖拽事件详解

    本文实例为大家分享了js鼠标拖拽事件的详细实现代码,供大家参考,具体内容如下 图片如下: css代码 <style> *{ margin:0; padding:0; } #box{ width: 200px; height: 200px; background: url("./img/aio.png") no-repeat; background-size: cover; position: absolute;/*定位元素 父级元素window就是初始包含块*/ top:0

  • 基于jQuery拖拽事件的封装

    本文实例为大家分享了基于jQuery封装的拖拽事件,供大家参考,具体内容如下 HTML代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <

  • WPF中鼠标/键盘/拖拽事件以及用行为封装事件详解

    目录 鼠标事件 键盘输入事件 拖拽事件 用行为封装事件 用事件来实现 用行为来封装 本文主要介绍了WPF中常用的鼠标事件.键盘事件以及注意事项,同时使用一个案例讲解了拓展事件.除此之外,本文还讲述如何用行为(Behavior)来封装事件. Windows中的事件通过消息机制来完成,也就是Windows系统来捕获用户输入(如鼠标点击.键盘输入),然后Windows发送一个消息给应用程序,应用程序进行具体的处理.在Winform中,窗体中每个控件都是有独立的句柄,也就是每个控件都可以收到Window

  • Sortable.js拖拽排序使用方法解析

    最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的. 官网: http://rubaxa.github.io/Sortable/ 拖拽的时候主要由这几个事件完成, ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上     ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上     ondragover 事件:拖拽元素在目

  • React 实现拖拽功能的示例代码

    本文介绍了React 实现拖拽功能的示例代码,分享给大家,具体如下: 实现效果: 因为工作中会用到 JIRA 所以想实现一下相似的功能,顺便学习一下 H5 的拖拽.不支持拖拽改变顺序,感觉有点麻烦,而且没必要.感觉相关的博文好少的,大部分都是直接上代码,没有解释. 图片默认可以拖动,其他元素的拖动效果同图片.正常的 div 是不能被拖动的,鼠标点击选择后移动没有效果,需要加  draggable="true" 使得元素可以被拖动. 拖拽相关的几个事件,有被拖动元素的事件,也有拖动进入的

随机推荐