简体   繁体   English

Pyqt5 可拖动 QPushButton

[英]Pyqt5 draggable QPushButton

I have this sample code on how to drag and move a QPushButton.我有关于如何拖动和移动 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_() 

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.您在 mouseReleaseEvent 中return ,这意味着您不会让按钮知道它实际上收到了鼠标释放,从而使状态保持为按下状态。

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.如果您将鼠标移动几个像素(低于曼哈顿长度),您可以看到它的行为是正确的,因此您必须完全删除该if块,或者如果您想在返回之前调用self.setDown(False)避免发送clicked信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM