欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-21 23:25:03
目录实现思路1、简要介绍qmimedata2、qmimedata的用例1在qt实现外部文件拖拽并展示3、qmimedata的用例2两个qlistwidget之间的item交换系列文章:pyqt5使用m...

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

实现思路

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

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

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

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 的原因如下图

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

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并非最初qdra*生信号的self,两个self在这里其实代表的分别是两个窗口

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

if drag.exec(qt.moveaction) == qt.moveaction:
   self.removesel()

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