In the following example, we will demonstrate how to drag & drop a button widget.
#!/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: January 2015
"""
import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QApplication
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag
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):
QPushButton.mousePressEvent(self, 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_()
In our code example, we have a QPushButton on the window. If we click on the button with a left mouse button, the 'press' message is printed to the console. By right clicking and moving the button, we perform a drag & drop operation on the button widget.
class Button(QPushButton):
def __init__(self, title, parent):
super().__init__(title, parent)
We create a Button class which derives from the QPushButton. We also reimplement two methods of the QPushButton: the mouseMoveEvent() and the mousePressEvent(). The mouseMoveEvent() method is the place where the drag & drop operation begins.
if e.buttons() != Qt.RightButton:
return
Here we decide that we can perform drag & drop only with a right mouse button. The left mouse button is reserved for clicking on the button.
mimeData = QMimeData()
drag = QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
The QDrag object is created. The class provides support for MIME-based drag and drop data transfer.
dropAction = drag.exec_(Qt.MoveAction)
The start() method of the drag object starts the drag & drop operation.
def mousePressEvent(self, e):
QPushButton.mousePressEvent(self, e)
if e.button() == Qt.LeftButton:
print('press')
We print 'press' to the console if we left click on the button with the mouse. Notice that we call mousePressEvent() method on the parent as well. Otherwise, we would not see the button being pushed.
position = e.pos()
self.button.move(position)
In the dropEvent() method we code what happens after we release the mouse button and finish the drop operation. We find out the current mouse pointer position and move the button accordingly.
e.setDropAction(Qt.MoveAction)
e.accept()
We specify the type of the drop action. In our case it is a move action.