PyQt5使用mimeData实现拖拽事件教程示例解析上
实现思路
1、简要介绍qmimedata
2、qmimedata的用例1:在qt实现输入框的文字拖拽
3、qmimedata的用例2:在qt实现按钮拖动
两个用例的实现效果如下:
用例1:
用例2:
1、简要介绍qmimedata
一、qdrag
首先是创建qdrag,可以在mousepressevent、mousemoveevent、dragmoveevent中创建。
qdrag在exec前,一定要设置qmimedata,否则不会开始拖拽操作。
qmimedata在拖拽中非常有用,可以用来保存拖拽操作附带的信息,比如字符串、文件或者图片,同时也可以用来验证其所保存的信息格式,并以此来判断是否可接收。
另外要注意,在windows下,qdrag::exec()是个同步操作,要在exec()返回后,才会继续执行下面的代码。
二、drag相关事件
首先,当需要一个控件接收drag和drop,就要先调用控件的方法:setacceptdrops(true)。
qt中一共有三个drag相关事件,dragenterevent、dragmoveevent、dragleaveevent。这三个事件触发条件类似鼠标移入,鼠标移动,鼠标移出。当鼠标拖拽进入控件触发dragenterevent,在控件内拖拽移动触发dragmoveevent,鼠标拖拽离开控件触发dragleaveevent。
三、dropevent
当drag为accept状态,然后释放鼠标,就会产生dropevent。我们可以在这个事件里处理本次拖拽附带的mime信息。
四、拖放关键逻辑图
2、qmimedata的用例1
在qt实现输入框的文字拖拽
# -*- coding: utf-8 -*- import sys from pyqt5.qtcore import qt, qmimedata from pyqt5.qtgui import qdrag from pyqt5.qtwidgets import qwidget, qlineedit, qapplication, qsplitter, qhboxlayout class mylineedit(qlineedit): def __init__(self, parent): super().__init__(parent) self.setacceptdrops(true) def dragmoveevent(self, event): drag = qdrag(self) mime = qmimedata() drag.setmimedata(mime) drag.exec(qt.copyaction) def dragenterevent(self, event): if event.mimedata().hastext(): event.accept() else: event.ignore() def dropevent(self, event): self.settext(event.mimedata().text()) event.source().settext("") class simpledrag(qwidget): def __init__(self): super().__init__() self.initui() def initui(self): hlayout = qhboxlayout(self) edit1 = mylineedit(self) edit1.setdragenabled(true) edit2 = mylineedit(self) edit2.setdragenabled(true) splitter = qsplitter(qt.horizontal) splitter.addwidget(edit1) splitter.addwidget(edit2) hlayout.addwidget(splitter) self.setlayout(hlayout) self.setwindowtitle('简易的拖动事件') if __name__ == '__main__': app = qapplication(sys.argv) ex = simpledrag() ex.show() app.exec_()
关键解析:
在自定义控件中:
1、我们创建了一个继承自qt的qlineedit的输入框
2、在dragmoveevent中创建了qdrag,并且设置了drag的mimedata,接着对qdrag调用exec方法
3、在dragenterevent中接收了该事件 即对应代码的 event.accept()
4、在dropevent 中 对事件进行了放的处理
在主窗口中:
1、设置该窗口可以接收拖拽事件setdragenabled(true)
这就完美对应上面的qmimedata的使用啦
3、qmimedata的用例2
在qt实现按钮拖动
# -*- coding: utf-8 -*- import sys from pyqt5.qtwidgets import qpushbutton, qwidget, qapplication from pyqt5.qtcore import qt, qmimedata from pyqt5.qtgui import qdrag class button(qpushbutton): def __init__(self, title, parent): super().__init__(title, parent) def mousemoveevent(self, e): if e.buttons() != qt.leftbutton: return mimedata = qmimedata() drag = qdrag(self) drag.setmimedata(mimedata) drag.sethotspot(e.pos() - self.rect().topleft()) drag.exec_(qt.moveaction) class example(qwidget): def __init__(self): super().__init__() self.initui() def initui(self): self.setacceptdrops(true) self.button = button('button', self) self.button.move(100, 65) self.setwindowtitle('click or move') self.setgeometry(300, 300, 280, 150) def dragenterevent(self, e): e.accept() def dropevent(self, e): position = e.pos() self.button.move(position) e.setdropaction(qt.moveaction) e.accept() if __name__ == '__main__': app = qapplication(sys.argv) ex = example() ex.show() app.exec_()
关键解析:
在自定义控件中:
1、我们创建了一个继承自qt的qpushbutton的按钮
2、在mousemoveevent中创建了qdrag,并且设置了drag的mimedata,接着对qdrag调用exec方法
在主窗口中:
1、设置该窗口可以接收拖拽事件setdragenabled(true)
2、在dropevent 中 对事件进行了放的处理,改变按钮的位置
1、在dragenterevent中接收了该事件 即对应代码的 event.accept()
第二个例子跟第一个有点不一样,因为第一个例子中,放的事件给到输入框 mylineedit
而第二个例子中,此时接收放事件的控件是主窗口 example(qwidget)
ps.后面还有一篇复杂的关于拖拽的使用,只是例子更为复杂,原理还是一样的
传送链接:
以上就是pyqt5使用mimedata实现拖拽事件教程示例解析上的详细内容,更多关于pyqt5拖拽事件mimedata使用的资料请关注其它相关文章!