Вам не нужно создавать подкласс для кнопки, чтобы переместить ее, и вам определенно не следует использовать перетаскивание, если вы собираетесь переместить объект в пределах одного и того же родителя.
Кроме того, если вы При проверке только тех движений, которые происходят, пока нажата правая кнопка, вы должны всегда вызывать базовую реализацию для других ситуаций (других кнопок или без кнопки, если mouseTracking
включен; обычно это не так с кнопками pu sh, но это не главное).
Установите на кнопки фильтр событий и отследите следующие события:
- QEvent.MouseButtonPress: если кнопка является правой, установите переменную для текущего движущегося виджета и другую с текущей позицией мыши (скажем, startPosition)
- QEvent.MouseMove: если текущий движущийся виджет существует, переместите его по формуле
newPosition = currentPosition + eventPosition - startPosition
- QEvent.MouseButtonRelease: очистить текущий движущийся виджет
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)