PyQt5使用mimeData实现拖拽事件教程示例解析下
作者:在逆境中蜕变 发布时间:2021-02-15 11:09:03
系列文章:
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()
来源:https://blog.csdn.net/weixin_40301728/article/details/113285997


猜你喜欢
- 官方网站 : www.python.orgPython is an interpreted, interactive, object-ori
- 1.背景看到这个标题你可能想一个分块能有什么难度?还值得细说吗,最近确实遇到一个有意思的分块函数,写法比较巧妙优雅,所以写一个分享。日前在做
- 本文实例讲述了Python3实现将文件归档到zip文件及从zip文件中读取数据的方法。分享给大家供大家参考。具体实现方法如下:'
- 目录需求背景思路分析UI展示开始使用一 编写支付组件模板二 支付组件的JS相关代码和说明附:组件JS完整的源码需求背景市场报告列表展示的报告
- 前言在Django的前后端分离项目中DRF(Django Restframe Work)框架无疑是首选,关于token验证一般使用的是JWT
- Reqeusts支持以form表单形式发送post请求,只需要将请求的参数构造成一个字典,然后传给requests.post()的data参
- 下载python3.6.5安装包1. 上传安装包。打开终端,利用命令cd 进入文件所在文件夹里python@ubun
- 人生苦短,快学Python!最近有位读者朋友遇到了一个小问题,私聊找小五答疑。感觉也会有其他同学会遇到,所以干脆分享出来。如下图所示,在本地
- 以下保存成 App.xml , 与asp文件放在相同目录下! 代码如下: <?xml version="1.0"
- 昨天遇到了一个奇怪的问题,在Python中需要传递dict参数,利用json.dumps将dict转为json格式用post方法发起请求:p
- 练手项目,先上图先实现一个简单的串口工具,为之后的上位机做准备代码如下:github 下载地址pyserial_demo.pyimport
- 前提是已设置ANDROID_HOME环境变量,使用aapt工具获取apk的信息,保存至脚本所在目录下的PackageInfo.txt文件中:
- 本文实例为大家分享了python3实现名片管理系统的具体代码,供大家参考,具体内容如下系统主要是:1.新增名片 2.显示全部 3.查询名片
- 在这里给出是的WindowsXP操作系统下的安装过程一、下载安装文件到MySQL官方网站找到ZIP文件提示:有些是安装文件,安装时会有提示,
- Jinja2需要Python2.4以上的版本。 安装 按照Jinja有多种方式,你可以根据需要选择不同的按照方式。 使用easy_insta
- 本文实例为大家分享了Vue实现简单跑马灯特效的具体代码,供大家参考,具体内容如下效果:点击按钮让文字动起来,点击停止按钮让文字停止知识点:s
- TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,
- 现在大部分网站都使用asp+access构建,这样的话通过下载access数据库简单就可以对网站进行破坏! 而很多的网站都不太重
- mysql等其他数据库中有随着记录的插入而表ID自动增长的功能,而oracle却没有这样的功能,我们有以下两种方式可以解决字段自增长的功能。
- 因为前端课要交一个大作业,刚好工作室的项目需要一个后台管理界面,就自学了一下vue,今天做了一个选项卡切换,最开始的作为菜鸡是用的js做的,