PyQt6 中的拖放
最后修改于 2023 年 1 月 10 日
在本 PyQt6 教程中,我们将介绍拖放操作。
在计算机图形用户界面中,拖放是指(或支持)点击虚拟对象并将其拖动到不同位置或另一个虚拟对象上的操作。一般来说,它可用于调用多种操作,或在两个抽象对象之间创建各种类型的关联。
拖放是图形用户界面的一部分。拖放操作使用户能够直观地执行复杂的操作。
通常,我们可以拖放两样东西:数据或一些图形对象。如果我们将图像从一个应用程序拖到另一个应用程序,我们拖放的是二进制数据。如果我们在 Firefox 中拖动一个标签并将其移动到另一个地方,我们拖放的是一个图形组件。
QDrag
QDrag
为基于 MIME 的拖放数据传输提供支持。它处理拖放操作的大部分细节。传输的数据包含在 QMimeData
对象中。
PyQt6 中的简单拖放示例
在第一个示例中,我们有一个 QLineEdit
和一个 QPushButton
。我们从行编辑小部件拖动纯文本,并将其放到按钮小部件上。按钮的标签将会改变。
#!/usr/bin/python """ ZetCode PyQt6 tutorial This is a simple drag and drop example. Author: Jan Bodnar Website: zetcode.com """ import sys from PyQt6.QtWidgets import (QPushButton, QWidget, QLineEdit, QApplication) class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent) self.setAcceptDrops(True) def dragEnterEvent(self, e): if e.mimeData().hasFormat('text/plain'): e.accept() else: e.ignore() def dropEvent(self, e): self.setText(e.mimeData().text()) class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): edit = QLineEdit('', self) edit.setDragEnabled(True) edit.move(30, 65) button = Button("Button", self) button.move(190, 65) self.setWindowTitle('Simple drag and drop') self.setGeometry(300, 300, 300, 150) def main(): app = QApplication(sys.argv) ex = Example() ex.show() app.exec() if __name__ == '__main__': main()
该示例演示了一个简单的拖放操作。
class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent) ...
为了在 QPushButton
小部件上放置文本,我们必须重新实现一些方法。因此,我们创建了自己的 Button
类,它继承自 QPushButton
类。
self.setAcceptDrops(True)
我们使用 setAcceptDrops
启用小部件的放置事件。
def dragEnterEvent(self, e): if e.mimeData().hasFormat('text/plain'): e.accept() else: e.ignore()
首先,我们重新实现 dragEnterEvent
方法。我们告知我们接受的数据类型。在我们的例子中,它是纯文本。
def dropEvent(self, e): self.setText(e.mimeData().text())
通过重新实现 dropEvent
方法,我们定义了在放置事件中发生的事情。在这里,我们更改按钮小部件的文本。
edit = QLineEdit('', self) edit.setDragEnabled(True)
QLineEdit
小部件内置了对拖动操作的支持。我们所需要做的就是调用 setDragEnabled
方法来激活它。

拖放按钮小部件
以下示例演示了如何拖放按钮小部件。
#!/usr/bin/python """ ZetCode PyQt6 tutorial In this program, we can press on a button with a left mouse click or drag and drop the button with the right mouse click. Author: Jan Bodnar Website: zetcode.com """ import sys from PyQt6.QtCore import Qt, QMimeData from PyQt6.QtGui import QDrag from PyQt6.QtWidgets import QPushButton, QWidget, QApplication class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent) def mouseMoveEvent(self, e): if e.buttons() != Qt.MouseButtons.RightButton: return mimeData = QMimeData() drag = QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(e.position().toPoint() - self.rect().topLeft()) dropAction = drag.exec(Qt.DropActions.MoveAction) def mousePressEvent(self, e): super().mousePressEvent(e) if e.button() == Qt.MouseButtons.LeftButton: print('press') 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, 550, 450) def dragEnterEvent(self, e): e.accept() def dropEvent(self, e): position = e.position() self.button.move(position.toPoint()) e.setDropAction(Qt.DropActions.MoveAction) e.accept() def main(): app = QApplication(sys.argv) ex = Example() ex.show() app.exec() if __name__ == '__main__': main()
在我们的代码示例中,我们在窗口上有一个 QPushButton
。如果我们用鼠标左键单击按钮,则会将“press”消息打印到控制台。通过右键单击并移动按钮,我们在按钮小部件上执行拖放操作。
class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent)
我们创建了一个从 QPushButton
派生的 Button
类。我们还重新实现了 QPushButton
的两种方法:mouseMoveEvent
和 mousePressEvent
。mouseMoveEvent
方法是拖放操作开始的地方。
if e.buttons() != Qt.MouseButtons.RightButton: return
在这里,我们决定只能使用鼠标右键执行拖放。鼠标左键保留用于单击按钮。
drag = QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(e.position().toPoint() - self.rect().topLeft())
创建了 QDrag
对象。该类为基于 MIME 的拖放数据传输提供支持。
dropAction = drag.exec(Qt.DropActions.MoveAction)
拖动对象的 exec
方法启动拖放操作。
def mousePressEvent(self, e): super().mousePressEvent(e) if e.button() == Qt.MouseButtons.LeftButton: print('press')
如果我们用鼠标左键单击按钮,则将“press”打印到控制台。请注意,我们还调用了父类的 mousePressEvent
方法。否则,我们将看不到按钮被按下。
position = e.pos() self.button.move(position)
在 dropEvent
方法中,我们指定了在释放鼠标按钮并完成放置操作后发生的事情。在我们的例子中,我们找出当前鼠标指针位置并相应地移动按钮。
e.setDropAction(Qt.MoveAction) e.accept()
我们使用 setDropAction
指定放置操作的类型。在我们的例子中,它是一个移动操作。
PyQt6 教程的这一部分专门介绍了拖放操作。