Reputation: 415
I have this sample code on how to drag and move a QPushButton. The only issue of that code is, when you drag the button and release it, the button status is stay as checked.
Can someone help me to change the code so that, after drag the button and release the button status is automatically unchecked. So, I don't have to click it to uncheck it.
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import Qt
class DragButton(QPushButton):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.globalPos()
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
# adjust offset from clicked point to origin of widget
currPos = self.mapToGlobal(self.pos())
globalPos = event.globalPos()
diff = globalPos - self.__mouseMovePos
newPos = self.mapFromGlobal(currPos + diff)
self.move(newPos)
self.__mouseMovePos = globalPos
super(DragButton, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.__mousePressPos is not None:
moved = event.globalPos() - self.__mousePressPos
if moved.manhattanLength() > 3:
event.ignore()
return
super(DragButton, self).mouseReleaseEvent(event)
def clicked():
print ("click as normal!")
if __name__ == "__main__":
app = QApplication([])
w = QWidget()
w.resize(800,600)
button = DragButton("Drag", w)
button.clicked.connect(clicked)
w.show()
app.exec_()
Upvotes: 2
Views: 1240
Reputation: 48479
You return
in the mouseReleaseEvent, which means that you're not letting the button know that it actually received a mouse release, thus leaving the status as pressed.
def mouseReleaseEvent(self, event):
if self.__mousePressPos is not None:
moved = event.globalPos() - self.__mousePressPos
if moved.manhattanLength() > 3:
event.ignore()
return # <-- the problem is here!
super(DragButton, self).mouseReleaseEvent(event)
You can see that it behaves correctly if you move the mouse by just a few pixels (below the Manhattan length), so you'll have to completely remove that if
block, or call self.setDown(False)
before returning if you want to avoid sending the clicked
signal.
Upvotes: 1