PySide 中的拖放
最后修改于 2023 年 10 月 18 日
在 PySide 教程的这一部分,我们讨论拖放操作。
在计算机图形用户界面中,拖放是指(或支持)点击虚拟对象并将其拖动到不同位置或另一个虚拟对象上的操作。通常,它可以用于调用许多种类的操作,或在两个抽象对象之间创建各种类型的关联。(维基百科)
拖放功能是图形用户界面中最明显的方面之一。拖放操作使用户能够直观地完成复杂的事情。
通常,我们可以拖放两样东西。数据或一些图形对象。如果我们将图像从一个应用程序拖到另一个应用程序,我们拖放二进制数据。如果我们在 Firefox 中拖动一个标签并将其移动到另一个地方,我们拖放一个图形组件。
简单的拖放
在第一个示例中,我们有一个 QtGui.QLineEdit
和一个 QtGui.QPushButton
。我们从行编辑小部件中拖动纯文本,然后将其放到按钮小部件上。
#!/usr/bin/python """ ZetCode PySide tutorial This is a simple drag and drop example. author: Jan Bodnar website: zetcode.com """ import sys from PySide import QtGui, QtCore class Button(QtGui.QPushButton): def __init__(self, title, parent): super(Button, self).__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(QtGui.QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): qe = QtGui.QLineEdit('', self) qe.setDragEnabled(True) qe.move(30, 65) button = Button("Button", self) button.move(190, 65) self.setGeometry(300, 300, 300, 150) self.setWindowTitle('Simple Drag & Drop') self.show() def main(): app = QtGui.QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) if __name__ == '__main__': main()
简单的拖放操作。
class Button(QtGui.QPushButton): def __init__(self, title, parent): super(Button, self).__init__(title, parent)
为了将文本放到 QtGui.QPushButton
小部件上,我们必须重新实现一些方法。所以我们创建了自己的 Button 类,它将继承自 QtGui.QPushButton
类。
self.setAcceptDrops(True)
我们为该小部件启用放置事件。
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
方法,我们定义了在放置事件发生时要做什么。这里我们更改了按钮小部件的文本。
qe = QtGui.QLineEdit('', self) qe.setDragEnabled(True)
QtGui.QLineEdit
小部件内置了对拖动操作的支持。我们所需要做的就是调用 setDragEnabled
方法来激活它。

拖放按钮小部件
在下面的示例中,我们演示了如何拖放一个按钮小部件。
#!/usr/bin/python """ ZetCode PySide tutorial In this example, we drag and drop a button. author: Jan Bodnar website: zetcode.com """ import sys from PySide import QtGui, QtCore class Button(QtGui.QPushButton): def __init__(self, title, parent): super(Button, self).__init__(title, parent) def mouseMoveEvent(self, e): if e.buttons() != QtCore.Qt.RightButton: return mimeData = QtCore.QMimeData() drag = QtGui.QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(e.pos() - self.rect().topLeft()) dropAction = drag.start(QtCore.Qt.MoveAction) def mousePressEvent(self, e): QtGui.QPushButton.mousePressEvent(self, e) if e.button() == QtCore.Qt.LeftButton: print 'press' class Example(QtGui.QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): self.setAcceptDrops(True) self.btn = Button('Button', self) self.btn.move(100, 65) self.setGeometry(300, 300, 300, 150) self.setWindowTitle('Click or move') self.show() def dragEnterEvent(self, e): e.accept() def dropEvent(self, e): position = e.pos() self.btn.move(position) e.setDropAction(QtCore.Qt.MoveAction) e.accept() def main(): app = QtGui.QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) if __name__ == '__main__': main()
在我们的代码示例中,我们在窗口上有一个 QtGui.QPushButton
。如果我们用鼠标左键单击该按钮,我们将打印“press”到控制台。通过右键单击并移动该按钮,我们对按钮小部件执行拖放操作。
class Button(QtGui.QPushButton): def __init__(self, title, parent): super(Button, self).__init__(title, parent)
我们创建一个 Button 类,它将派生自 QtGui.QPushButton
。我们还重新实现了 QtGui.QPushButton
的两种方法,即 mouseMoveEvent
和 mousePressEvent
。mouseMoveEvent()
方法是拖放操作开始的地方。
if event.buttons() != QtCore.Qt.RightButton: return
在这里,我们决定只能使用鼠标右键执行拖放。鼠标左键用于单击按钮。
mimeData = QtCore.QMimeData() drag = QtGui.QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(event.pos() - self.rect().topLeft())
在这里我们创建一个 QtGui.QDrag
对象。
dropAction = drag.start(QtCore.Qt.MoveAction)
拖动对象的 start
方法启动拖放操作。
def mousePressEvent(self, e): QtGui.QPushButton.mousePressEvent(self, e) if e.button() == QtCore.Qt.LeftButton: print 'press'
如果我们用鼠标左键单击该按钮,我们将打印“press”到控制台。请注意,我们也会在父级上调用 mousePressEvent
方法。否则,我们将看不到按钮被按下。
position = e.pos() self.btn.move(position)
在 dropEvent
方法中,我们编写了在释放鼠标按钮并完成放置操作后发生的事情。我们找出当前鼠标指针的位置并相应地移动一个按钮。
e.setDropAction(QtCore.Qt.MoveAction) e.accept()
我们指定放置操作的类型。在我们的例子中,它是一个移动操作。
PySide 教程的这一部分专门介绍了拖放。