在GUI里,拖放是指用户点击一个虚拟的对象,拖动,而后放置到另一个对象上面的动做。通常状况下,须要调用不少动做和方法,建立不少变量。python
拖放能让用户很直观的操做很复杂的逻辑。app
通常状况下,咱们能够拖放两种东西:数据和图形界面。把一个图像从一个应用拖放到另一个应用上的实质是操做二进制数据。把一个表格从Firefox上拖放到另一个位置 的实质是操做一个图形组。函数
本例使用了QLineEdit
和QPushButton
。把一个文本从编辑框里拖到按钮上,更新按钮上的标签(文字)。ui
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial This is a simple drag and drop example. Author: Jan Bodnar Website: zetcode.com Last edited: August 2017 """ from PyQt5.QtWidgets import (QPushButton, QWidget, QLineEdit, QApplication) import sys 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) if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() ex.show() app.exec_()
class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent) self.setAcceptDrops(True)
为了完成预约目标,咱们要重构一些方法。首先用QPushButton
上构造一个按钮实例。this
self.setAcceptDrops(True)
激活组件的拖拽事件。spa
def dragEnterEvent(self, e): if e.mimeData().hasFormat('text/plain'): e.accept() else: e.ignore()
首先,咱们重构了dragEnterEvent()
方法。设定好接受拖拽的数据类型(plain text)。code
def dropEvent(self, e): self.setText(e.mimeData().text())
而后重构dropEvent()
方法,更改按钮接受鼠标的释放事件的默认行为。orm
edit = QLineEdit('', self) edit.setDragEnabled(True)
QLineEdit
默认支持拖拽操做,因此咱们只要调用setDragEnabled()
方法使用就好了。对象
程序展现:继承
这个例子展现怎么拖放一个button组件。
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 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 Last edited: August 2017 """ from PyQt5.QtWidgets import QPushButton, QWidget, QApplication from PyQt5.QtCore import Qt, QMimeData from PyQt5.QtGui import QDrag import sys class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent) def mouseMoveEvent(self, e): if e.buttons() != Qt.RightButton: return mimeData = QMimeData() drag = QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(e.pos() - self.rect().topLeft()) dropAction = drag.exec_(Qt.MoveAction) def mousePressEvent(self, e): super().mousePressEvent(e) if e.button() == Qt.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, 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_()
上面的例子中,窗口上有一个QPushButton
组件。左键点击按钮,控制台就会输出press
。右键能够点击而后拖动按钮。
class Button(QPushButton): def __init__(self, title, parent): super().__init__(title, parent)
从QPushButton
继承一个Button
类,而后重构QPushButton
的两个方法:mouseMoveEvent()
和mousePressEvent()
.mouseMoveEvent()
是拖拽开始的事件。
if e.buttons() != Qt.RightButton: return
咱们只劫持按钮的右键事件,左键的操做仍是默认行为。
mimeData = QMimeData() drag = QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(e.pos() - self.rect().topLeft())
建立一个QDrag
对象,用来传输MIME-based数据。
dropAction = drag.exec_(Qt.MoveAction)
拖放事件开始时,用到的处理函数式start()
.
def mousePressEvent(self, e): QPushButton.mousePressEvent(self, e) if e.button() == Qt.LeftButton: print('press')
左键点击按钮,会在控制台输出“press”。注意,咱们在父级上也调用了mousePressEvent()
方法,否则的话,咱们是看不到按钮按下的效果的。
position = e.pos() self.button.move(position)
在dropEvent()
方法里,咱们定义了按钮按下后和释放后的行为,得到鼠标移动的位置,而后把按钮放到这个地方。
e.setDropAction(Qt.MoveAction) e.accept()
指定放下的动做类型为moveAction。
程序展现:
这个就一个按钮,没啥可展现的,弄GIF太麻烦了。