drag and drop a button widget.
代码:
# coding='utf-8'
from PyQt5.QtWidgets import QApplication, QWidget,\
QPushButton
from PyQt5.QtGui import QDrag
from PyQt5.QtCore import Qt, QMimeData
import sys
class Button(QPushButton):
def __init__(self, title, parent):
super().__init__(title, parent)
# This the place where the drag and drop operation begins.
def mouseMoveEvent(self, e) -> None:
# The MouseButtons class is a\
# set of flags whose values are\
# the members of the MouseButton\
# enum. Instances of the class\
# support the standard Python int methods.
# Here we decide that we can perform\
# drag and drop only with a right mouse\
# button. The left mouse button is\
# reserved for clicking on the button.
# 注意这里必须要用按键的枚举值:buttons,不能用button,\
# 可能是因为右键按下的操作是一个持久拖拉的过程,\
# 而不是像点击那样一下子就能完成,所以要用枚举值\
# (这些枚举值按键里面有右键就行)
if e.buttons() != Qt.RightButton:
return
# The QMimeData class provides a container\
# for data that records information about\
# its MIME type.
mime_data = QMimeData()
# QDrag对象的实例化支持MIME-based的拖拉操作使得数据转换
drag = QDrag(self)
drag.setMimeData(mime_data)
drag.setHotSpot(e.pos() - self.rect().topLeft())
# 从这个exec_方法开始拖或者拉的操作
dropAction = drag.exec_(Qt.MoveAction)
def mousePressEvent(self, e) -> None:
# Notice that we call mousePressEvent()\
# method on the parent as well. Otherwise,\
# we would not see the button being pushed.
# 就是说我们重写了别人父类的方法,但是还想用别人父类的方法,\
# 就必须要手动调用父类这个方法
super().mousePressEvent(e)
# 如果是左键的按下
if e.button() == Qt.LeftButton:
print('press')
class Gui(QWidget):
def __init__(self):
super(Gui, self).__init__()
self.start()
def start(self):
# 使得主窗体能够被拖/拉后放置在主窗体的某个地方
self.setAcceptDrops(True)
self.button = Button('按钮', self)
self.button.move(100, 65)
self.setGeometry(300, 300, 280, 150)
self.setWindowTitle('点击按钮或者移动它')
self.show()
# 当抓取操作开始,鼠标点击了但是还没放开
def dragEnterEvent(self, e) -> None:
# 无论主窗体上拖动的东西是何种类型,都能接受-->下一步的放下,
# 如果不接受(e.ignore)的话,拖动后是不能松手放下去的
e.accept()
# 紧按着的鼠标放开了(拖拉到了某个位置)
def dropEvent(self, e) -> None:
# 我们这个 程序不是开始拖拽后控件就一直跟着鼠标,\
# 只是松手后控件move过去.
# 立刻获得当前(拖动后)的位置
position = e.pos()
# 把按钮移动到拖动后的位置
self.button.move(position)
# 使得drop 操作的类型具体化(具体化成move action)
e.setDropAction(Qt.MoveAction)
# 也是使得主窗体每个地方都能放下拖拉后的控件,\
# 感觉这个无论是ignore还是accept都没有太大的影响
e.ignore()
app = QApplication(sys.argv)
gui = Gui()
sys.exit(app.exec_())
运行结果:左键点击:
image.png
右键拖拉: image.png
网友评论