python3+PyQt5重新实现自定义数据拖放处理
程序员文章站
2023-10-18 20:11:45
本文分成两部分,第一部分通过python3+pyqt5实现自定义数据的拖放操作。第二部分则对第一部分的程序进行修改,增加拖放操作时,菜单提示是否移动或拷贝,还有可以通过ct...
本文分成两部分,第一部分通过python3+pyqt5实现自定义数据的拖放操作。第二部分则对第一部分的程序进行修改,增加拖放操作时,菜单提示是否移动或拷贝,还有可以通过ctrl键盘来设置移动过程中拷贝源而非会将源删除。
自定义数据mime数据类型qmimedata,mime是一种用于处理具有多个组成部分的自定义数据的标准化格式。mime数据由一个数据类型和一个子类型构成–例如,text/plain,text/html,image/png,要处理自定义mime数据,就必须要选用一种自定义数据类型和一种子类型,然后将数据封装到qmimedata对象中。本例子中,我们创建端为application/x-icon-and-text类型的新mime数据。
注:
dragenterevent这是一个拖拽事件的函数,我们把文件拖拽进程序界面打开,之前必须setacceptdrops(true)了以后拖拽,但是只设置acceptdrops还不够,还需要在dragenterevent事件中对拖入的对象进行筛选,判断mimedata的类型是否是你能处理的,如果是,则调用event.acceptproposedaction()放行。拖放结束后会产生dropevent事件,在那里进行最后的放置操作。总之这是拖拽事件函数的一个筛选事件并放置的函数。
第一部分:
#!/usr/bin/env python3 import os import sys from pyqt5.qtcore import (qbytearray, qdatastream, qiodevice, qmimedata, qpoint, qsize, qt) from pyqt5.qtwidgets import (qapplication, qdialog,qgridlayout, qlineedit, qlistwidget,qlistwidgetitem, qwidget) from pyqt5.qtgui import qicon,qcolor,qpainter,qfontmetricsf,qdrag class droplineedit(qlineedit): def __init__(self, parent=none): super(droplineedit, self).__init__(parent) self.setacceptdrops(true) def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.setdropaction(qt.copyaction) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) text = "" #stream >> text text=stream.readqstring() self.settext(text) event.setdropaction(qt.copyaction) event.accept() else: event.ignore() class dndlistwidget(qlistwidget): def __init__(self, parent=none): super(dndlistwidget, self).__init__(parent) self.setacceptdrops(true) self.setdragenabled(true) def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.setdropaction(qt.moveaction) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) text = "" icon = qicon() #stream >> text >> icon text=stream.readqstring() stream >> icon item = qlistwidgetitem(text, self) item.seticon(icon) event.setdropaction(qt.moveaction) event.accept() else: event.ignore() def startdrag(self, dropactions): item = self.currentitem() icon = item.icon() data = qbytearray() stream = qdatastream(data, qiodevice.writeonly) #stream << item.text() << icon stream.writeqstring(item.text()) stream << icon mimedata = qmimedata() mimedata.setdata("application/x-icon-and-text", data) drag = qdrag(self) drag.setmimedata(mimedata) pixmap = icon.pixmap(24, 24) drag.sethotspot(qpoint(12, 12)) drag.setpixmap(pixmap) if drag.exec(qt.moveaction) == qt.moveaction: self.takeitem(self.row(item)) class dndwidget(qwidget): def __init__(self, text, icon=qicon(), parent=none): super(dndwidget, self).__init__(parent) self.setacceptdrops(true) self.text = text self.icon = icon def minimumsizehint(self): fm = qfontmetricsf(self.font()) if self.icon.isnull(): return qsize(fm.width(self.text), fm.height() * 1.5) return qsize(34 + fm.width(self.text), max(34, fm.height() * 1.5)) def paintevent(self, event): height = qfontmetricsf(self.font()).height() painter = qpainter(self) painter.setrenderhint(qpainter.antialiasing) painter.setrenderhint(qpainter.textantialiasing) painter.fillrect(self.rect(), qcolor(qt.yellow).lighter()) if self.icon.isnull(): painter.drawtext(10, height, self.text) else: pixmap = self.icon.pixmap(24, 24) painter.drawpixmap(0, 5, pixmap) painter.drawtext(34, height, self.text + " (drag to or from me!)") def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.setdropaction(qt.copyaction) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) self.text = "" self.icon = qicon() #stream >> self.text >> self.icon self.text=stream.readqstring() stream>>self.icon event.setdropaction(qt.copyaction) event.accept() self.updategeometry() self.update() else: event.ignore() def mousemoveevent(self, event): self.startdrag() qwidget.mousemoveevent(self, event) def startdrag(self): icon = self.icon if icon.isnull(): return data = qbytearray() stream = qdatastream(data, qiodevice.writeonly) #stream << self.text << icon stream.writeqstring(self.text) stream<<icon mimedata = qmimedata() mimedata.setdata("application/x-icon-and-text", data) drag = qdrag(self) drag.setmimedata(mimedata) pixmap = icon.pixmap(24, 24) drag.sethotspot(qpoint(12, 12)) drag.setpixmap(pixmap) drag.exec(qt.copyaction) class form(qdialog): def __init__(self, parent=none): super(form, self).__init__(parent) dndlistwidget = dndlistwidget() path = os.path.dirname(__file__) for image in sorted(os.listdir(os.path.join(path, "images"))): if image.endswith(".png"): item = qlistwidgetitem(image.split(".")[0].capitalize()) item.seticon(qicon(os.path.join(path, "images/{0}".format(image)))) dndlistwidget.additem(item) dndiconlistwidget = dndlistwidget() dndiconlistwidget.setviewmode(qlistwidget.iconmode) dndwidget = dndwidget("drag to me!") droplineedit = droplineedit() layout = qgridlayout() layout.addwidget(dndlistwidget, 0, 0) layout.addwidget(dndiconlistwidget, 0, 1) layout.addwidget(dndwidget, 1, 0) layout.addwidget(droplineedit, 1, 1) self.setlayout(layout) self.setwindowtitle("custom drag and drop") if __name__ == "__main__": app = qapplication(sys.argv) form = form() form.show() app.exec_()
运行结果:
第二部分:
#!/usr/bin/env python3 import os import sys from pyqt5.qtcore import (qbytearray, qdatastream, qiodevice, qmimedata, qpoint, qsize, qt) from pyqt5.qtwidgets import (qapplication, qdialog,qgridlayout, qlineedit, qlistwidget,qlistwidgetitem, qwidget,qmenu) from pyqt5.qtgui import qicon,qcolor,qpainter,qfontmetricsf,qdrag,qcursor class droplineedit(qlineedit): def __init__(self, parent=none): super(droplineedit, self).__init__(parent) self.setacceptdrops(true) def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.setdropaction(qt.copyaction) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) text = "" text=stream.readqstring() self.settext(text) event.setdropaction(qt.copyaction) event.accept() else: event.ignore() class dndmenulistwidget(qlistwidget): def __init__(self, parent=none): super(dndmenulistwidget, self).__init__(parent) self.setacceptdrops(true) self.setdragenabled(true) self.dropaction = qt.copyaction def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.setdropaction(qt.moveaction) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) text = "" icon = qicon() text=stream.readqstring() stream>>icon menu = qmenu(self) menu.addaction("©", self.setcopyaction) menu.addaction("&move", self.setmoveaction) if menu.exec_(qcursor.pos()): item = qlistwidgetitem(text, self) item.seticon(icon) event.setdropaction(self.dropaction) event.accept() return else: event.setdropaction(qt.ignoreaction) event.ignore() def setcopyaction(self): self.dropaction = qt.copyaction def setmoveaction(self): self.dropaction = qt.moveaction def startdrag(self, dropactions): item = self.currentitem() icon = item.icon() data = qbytearray() stream = qdatastream(data, qiodevice.writeonly) stream.writeqstring(item.text()) stream<<icon mimedata = qmimedata() mimedata.setdata("application/x-icon-and-text", data) drag = qdrag(self) drag.setmimedata(mimedata) pixmap = icon.pixmap(24, 24) drag.sethotspot(qpoint(12, 12)) drag.setpixmap(pixmap) if (drag.exec(qt.moveaction|qt.copyaction) == qt.moveaction): self.takeitem(self.row(item)) class dndctrllistwidget(qlistwidget): def __init__(self, parent=none): super(dndctrllistwidget, self).__init__(parent) self.setacceptdrops(true) self.setdragenabled(true) def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): action = qt.moveaction if event.keyboardmodifiers() & qt.controlmodifier: action = qt.copyaction event.setdropaction(action) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) text = "" icon = qicon() text=stream.readqstring() stream>>icon item = qlistwidgetitem(text, self) item.seticon(icon) action = qt.moveaction if event.keyboardmodifiers() & qt.controlmodifier: action = qt.copyaction event.setdropaction(action) event.accept() else: event.ignore() def startdrag(self, dropactions): item = self.currentitem() icon = item.icon() data = qbytearray() stream = qdatastream(data, qiodevice.writeonly) stream.writeqstring(item.text()) stream<<icon mimedata = qmimedata() mimedata.setdata("application/x-icon-and-text", data) drag = qdrag(self) drag.setmimedata(mimedata) pixmap = icon.pixmap(24, 24) drag.sethotspot(qpoint(12, 12)) drag.setpixmap(pixmap) if (drag.exec(qt.moveaction|qt.copyaction) == qt.moveaction): self.takeitem(self.row(item)) class dndwidget(qwidget): def __init__(self, text, icon=qicon(), parent=none): super(dndwidget, self).__init__(parent) self.setacceptdrops(true) self.text = text self.icon = icon def minimumsizehint(self): fm = qfontmetricsf(self.font()) if self.icon.isnull(): return qsize(fm.width(self.text), fm.height() * 1.5) return qsize(34 + fm.width(self.text), max(34, fm.height() * 1.5)) def paintevent(self, event): height = qfontmetricsf(self.font()).height() painter = qpainter(self) painter.setrenderhint(qpainter.antialiasing) painter.setrenderhint(qpainter.textantialiasing) painter.fillrect(self.rect(), qcolor(qt.yellow).lighter()) if self.icon.isnull(): painter.drawtext(10, height, self.text) else: pixmap = self.icon.pixmap(24, 24) painter.drawpixmap(0, 5, pixmap) painter.drawtext(34, height, self.text + " (drag to or from me!)") def dragenterevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.accept() else: event.ignore() def dragmoveevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): event.setdropaction(qt.copyaction) event.accept() else: event.ignore() def dropevent(self, event): if event.mimedata().hasformat("application/x-icon-and-text"): data = event.mimedata().data("application/x-icon-and-text") stream = qdatastream(data, qiodevice.readonly) self.text = "" self.icon = qicon() self.text=stream.readqstring() stream>>self.icon event.setdropaction(qt.copyaction) event.accept() self.updategeometry() self.update() else: event.ignore() def mousemoveevent(self, event): self.startdrag() qwidget.mousemoveevent(self, event) def startdrag(self): icon = self.icon if icon.isnull(): return data = qbytearray() stream = qdatastream(data, qiodevice.writeonly) stream.writeqstring(self.text) stream<<icon mimedata = qmimedata() mimedata.setdata("application/x-icon-and-text", data) drag = qdrag(self) drag.setmimedata(mimedata) pixmap = icon.pixmap(24, 24) drag.sethotspot(qpoint(12, 12)) drag.setpixmap(pixmap) drag.exec(qt.copyaction) class form(qdialog): def __init__(self, parent=none): super(form, self).__init__(parent) dndlistwidget = dndmenulistwidget() path = os.path.dirname(__file__) for image in sorted(os.listdir(os.path.join(path, "images"))): if image.endswith(".png"): item = qlistwidgetitem(image.split(".")[0].capitalize()) item.seticon(qicon(os.path.join(path, "images/{0}".format(image)))) dndlistwidget.additem(item) dndiconlistwidget = dndctrllistwidget() dndiconlistwidget.setviewmode(qlistwidget.iconmode) dndwidget = dndwidget("drag to me!") droplineedit = droplineedit() layout = qgridlayout() layout.addwidget(dndlistwidget, 0, 0) layout.addwidget(dndiconlistwidget, 0, 1) layout.addwidget(dndwidget, 1, 0) layout.addwidget(droplineedit, 1, 1) self.setlayout(layout) self.setwindowtitle("custom drag and drop") if __name__ == "__main__": app = qapplication(sys.argv) form = form() form.show() app.exec_()
运行结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 李承乾为什么备受宠爱还要*?李世民也不是一点错没有!
下一篇: 使用php清除bom示例