PyQt: 拖放事件(Drag & Drop)

拖放,通过拖拽一个或者多个对象来完成相应的移动、复制等操作。拖放在我们使用的程序应用中是一个非常常见的操作,也是一个非常实用的操作。

Pyqt的拖放事件是基于MIME的拖放。QMimeData对象存储着相关的数据并对应着某种MIME类型,该对象存储在剪贴板上以便应用于拖放过程。

QMimeData类的函数支持一些MIME类型的检测。

Tester Getter Setter MIME Types
hasText() text() setText() text/plain
hasHtml() html() setHtml() text/html
hasUrls() urls() setUrls() text/uri-list
hasImage() imageData() setImageData() image/ *
hasColor() colorData() setColorData() application/x-color

拖放事件并不仅仅局限于处理文本和图像数据,任何类型的数据都可以在拖放操作中进行传递。为了可以在不同的应用中“拖”信息,这些应用必须标明他们可以接受或者产生哪些类型的数据。而MIME 类型就可以满足这一要求。 QDrag 对象在构建的时候就包含了一个MIME类型的列表来表征数据,且被接受的部件对象会利用这个来获取数据。对于通用的数据类型,可以非常方便地使用上述函数来进行处理,而对于用户自定义数据类型,则很有必要进行显式的声明。

为了支持额外的媒体类型(media type), 可以简单的通过 QMimeData 对象的 setData() 函数来进行数据的设置。该函数可以适用于所有的MIME类型和包含合适数据类型的 QByteArray 对象。

pyqt中的很多widget都支持拖放事件,而拖放事件也有好几个重要的类。

QDrag :支持基于MIME的拖放数据转移器。
DragEnterEvent : 当被拖动的对象移动到可以可以接受操作的widget时会触发该方法。
DragMoveEvent :当拖放操作在执行过程中触发。
DragLeaveEvent :当拖放操作离开当前widget时触发。
DropEvent :当拖放操作结束时触发。

Note: 以上的触发前置条件是当前区域(widget)可以接受拖放,这个可以通过setAccepteDrops(True)函数来激活。

在最简单的例子中,拖放行为的目标(target)会接收一份被“拖”对象的copy,并且数据的“源”会考虑是不是删除原始数据,而这一个结果将由 CopyAction 行为决定。当然,target也会处理其他类型的行为,如 MoveAction LinkAction 等行为。如果“源”(source)调用 QDrag 对象的 exec() 并且返回一个 MoveAction ,那么“源”就需要自己选择是否删除原始数据。被源部件创建的 QMimeData QDrag 对象最好不被删除。目标部件通常会保存原始数据的引用。

Dragging

开始“拖”操作,需要创建一个 QDrag 对象,并调用exec()函数。在大多数应用中,最好的实现方式就是通过鼠标来进行。当鼠标被按下且光标移动到目的区域时释放就完成了拖放操作。因此,最简单实现拖放操作就是重写widget的 mousePressEvent()

def mousePresseEvent(self, event)
    if event.button() == Qt.LeftButton
        drag = QDrag()
        mimedata = QMimeData
        mimedata.setText('aaa')#放入数据
        drag.setMimeData(mimedata)
        drag.exec_() #exec()函数并不会阻塞主函数

上述是最简单的’拖’操作定义方式。当然,为了避免功能冲突,也可以在 mouseMoveEvent() 中进行该操作的定义。

Droping

为了使得相关的widget能够响应释放操作,需要使用 setAcceptDrops(True) 并且重写相关的 dragEnterEvent() dropEvent() 函数。在重写 dragMoveEvent() dropEvent() 函数之前,必须先重写 dropEnter() 函数。而 dropEnter() 通常用来判断 当前widget是否接受操作带有的数据类型。而 dropEvent() 通常是用来处理被释放的数据。

def dragEnterEvent(self, event)
    event.acceptProposedAction()
def dropEvent(self, event)
    #To Do

Reference

[1] PyQt - Drag & Drop
[2] Qt Documentation: Drag and Drop
[3] Qt Documentation: QMimeData Class
[4] PyQt4 - Drag and Drop

在G UI 里, 拖放 是指用户点击一个虚拟的对象,拖动,然后放置到另外一个对象上面的动作。一般情况下,需要调用很多动作和方法,创建很多变量。 拖放 能让用户很直观的操作很复杂的逻辑。 一般情况下,我们可以 拖放 两种东西:数据和图形界面。把一个图像从一个应用 拖放 到另外一个应用上的实质是操作二进制数据。吧一个表格从Firefox上 拖放 到另外一个位置 的实质是操作一个 为用户提供的拖曳功能很直观,在很对桌面应用程序中,复制或移动对象都可以通过拖曳来完成 基于MIME类型的拖曳数据传输是基于Q Drag 类的,QMimeData对象将关联的数据与其对应的MIME类型相关联 MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协...
多个按钮 drag & drop 互不干扰 急急忙忙接触 PyQt 5想做一个辅助测试的小程序,涉及到多个按钮在界面上自由 拖放 ,然而找来找去只找到如下 drag & drop 单个按钮的例子: from PyQt 5. Qt Widgets import QPushButton, QWidget, QApplication from PyQt 5. Qt Core import Qt , QMimeData fro...
最近在自学 Pyqt 5界面开发,想实现拖拽功能,网上查到的都是通过改写控件的类实现的。因为本人是菜鸟,所以界面是在 Qt Designer下设计再生成py文件,如果改写类的话,更新 ui 时需要修改相应py文件,并且同一种拖拽功能,在不同控件上实现是需要重写一遍类,略显麻烦,所以想通过不采用改写类的方法实现拖拽功能,经过查找资料,到达预期目标。 参考文献: 1.改写实例方法:https://www.cnblogs.com/ly570/p/10942311.html 2.改写类实现拖拽功能:https://b
PyQt 5之 Drag 拖曳功能 在很多桌面应用程序中,复制或移动对象都可以通过拖曳来完成。基于MIME类型的拖曳数据传输是基于 Drag 类的。QMimeData对象将关联的数据与其对应的MIME类型相关联。 一、MIME类型 MIME类型的数据可以简单理解为互联网上的各种资源,比如文本、音频和视频资源等,互联网上的每一种资源都属于一种MIME类型的数据。 在 PyQt 5教程的这一部分中,我们将讨论 拖放 操作。 在计算机图形用户界面中, 拖放 是单击虚拟对象并将其拖动到其他位置或另一个虚拟对象的动作(或支持其操作)。通常,它可用于调用多种操作,或在两个抽象对象之间创建各种类型的关联。 拖放 是图形用户界面的一部分。 拖放 操作使用户能够直观地执行复杂操...
参考:https://blog.csdn.net/jia666666/article/details/81568326 为用户提供拖拽功能很直观,在很多桌面应用程序中,复制和移动对象都可以通过拖拽来完成 基于MIME类型的拖曳数据传输是基于Q Drag 类的,QMimeData对象将关联的数据与其对应的MIME类型相关联 MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送...
Python PyQt 5的select 事件 是指当用户在选择文本框或组合框中的一个或多个项目时触发的 事件 。这个 事件 可以用来处理一些关键的任务,例如根据用户的选择更新界面或执行某些操作。 在 PyQt 5中,select 事件 可以通过重写QWidget的focusInEvent()和focusOutEvent()函数来实现。当文本框或组合框获取焦点时,focusInEvent()会被调用,让我们可以在该函数中执行代码以响应用户的选择。当失去焦点时,focusOutEvent()函数会被调用,让我们可以执行一些其他的清理工作。 此外, PyQt 5也提供了QComboBox和QLineEdit等内置组件,它们已经默认包含了select 事件 的响应函数。因此,使用这些组件时可以省略自己实现select 事件 响应的代码。 总之,Python PyQt 5的select 事件 是处理用户在文本框或组合框中进行选择时的重要 事件 ,它可以通过重写焦点 事件 函数或直接使用内置组件来实现响应。