在PyQ中拖动/移动QPushButton

2024-09-29 05:19:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我真的很努力想办法做到这一点。假设我在小部件窗口中非常简单地实现一个按钮:

self.button = QPushButton("Drag Me", self)

我可以使用self.button.move(x,y)将它的初始化点移动到父窗口小部件的区域,并且可以通过e.x()e.y()mousePressEvent(self, e)获取鼠标事件,这样按钮就可以移动到我单击的任何位置,但是我似乎无法将所有这些放在一起成为一个拖放框架。

澄清:在阅读了拖放的“真正”含义之后,我并不需要这样做。我只想用鼠标移动一个小部件,就像你移动冰箱上的磁铁一样。


Tags: self框架区域move部件事件button鼠标
2条回答

这取决于你想做什么。如果你想做真正的“拖放”,那你就错了。你所做的只是在它的父对象的X,Y坐标空间中移动按钮。它从未真正调用任何拖放事件,它们完全不同。

您应该在此处阅读拖放文档:

http://doc.qt.nokia.com/4.7-snapshot/dnd.html
http://qt-project.org/doc/qt-5.0/qdrag.html

您需要创建一个新的QDrag对象并执行它,而不是在mousePressEvent中移动按钮。通过使用QPixmap::grabWidget方法对按钮进行快照并使用QDrag::setPixmap方法将其分配给QDrag实例,可以使其看起来像您的按钮。

如果您只想在父空间中移动小部件,我建议您使用此框架并只接受按钮的drop事件。那你就不会触发一堆不必要的重画。

下面是一个可移动按钮的示例,该按钮仍然正确地支持正常的单击信号:

from PyQt4 import QtCore, QtGui


class DragButton(QtGui.QPushButton):

    def mousePressEvent(self, event):
        self.__mousePressPos = None
        self.__mouseMovePos = None
        if event.button() == QtCore.Qt.LeftButton:
            self.__mousePressPos = event.globalPos()
            self.__mouseMovePos = event.globalPos()

        super(DragButton, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() == QtCore.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 = QtGui.QApplication([])
    w = QtGui.QWidget()
    w.resize(800,600)

    button = DragButton("Drag", w)
    button.clicked.connect(clicked)

    w.show()
    app.exec_()

mousePressEvent中,我记录初始开始位置,以及在整个拖动过程中更新的位置。

mouseMoveEvent中,我得到了小部件从单击位置到实际原点的适当偏移量,这样移动是准确的。

mouseReleaseEvent中,我检查整个移动量是否至少大于一小部分。如果是,那么它是一个拖拽,我们忽略了正常事件,不会产生“点击”信号。否则,我们允许普通事件处理程序生成click。

相关问题 更多 >