Reputation: 67
There are two buttons on the window called Button1 and Button2. In the code below, I can move it by right-clicking the button named Button1. Button1 moves again when I want to right-click and drag Button2. But I can't move Button2 with the code below. I want to move which one of these two buttons right click.How can I do that?
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.button1 = Button('Button1', self)
self.button1.setFixedSize(100,100)
self.button1.move(0, 0)
self.button2 = Button('Button2', self)
self.button2.move(0, 110)
self.setWindowTitle('Click or Move')
self.setGeometry(0, 0, 400, 400)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
position = e.pos()
print(position)
self.button1.move(position)
e.setDropAction(Qt.MoveAction)
e.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
Upvotes: 0
Views: 184
Reputation: 48260
You don't need to subclass a button to move it, and you certainly shouldn't use drag&drop if you're going to move the object within the same parent.
Also, if you're going to check only movements that happen while the right button is pressed, you should always call the base implementation for the other situations (other buttons, or no button, in case mouseTracking
is enabled; it's not usually the case with push buttons, but that's not the point).
Install an event filter on the buttons, and track the following events:
newPosition = currentPosition + eventPosition - startPosition
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.movingButton = None
def initUI(self):
self.button1 = QPushButton('Button1', self)
self.button1.setFixedSize(100,100)
# no need for this, every new widget is always placed at (0, 0)
# self.button1.move(0, 0)
self.button1.installEventFilter(self)
self.button2 = QPushButton('Button2', self)
self.button2.move(0, 110)
self.button2.installEventFilter(self)
self.setWindowTitle('Click or Move')
self.setGeometry(0, 0, 400, 400)
def eventFilter(self, source, event):
if source in (self.button1, self.button2):
if event.type() == QEvent.MouseButtonPress and event.button() == Qt.RightButton:
self.movingButton = source
self.startPos = event.pos()
# uncomment the following lines if you want to move the button while
# moving the mouse
# elif event.type() == QEvent.MouseMove and self.movingButton:
# self.movingButton.move(source.pos() + event.pos() - self.startPos)
elif event.type() == QEvent.MouseButtonRelease and self.movingButton:
self.movingButton.move(source.pos() + event.pos() - self.startPos)
self.movingButton = None
return super().eventFilter(source, event)
Upvotes: 2