在 PyQt 中拖动/移动 QPushButton [英] Dragging/Moving a QPushButton in PyQt

查看:33
本文介绍了在 PyQt 中拖动/移动 QPushButton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很难找到一种方法来做到这一点.假设我在小部件窗口中非常简单地实现了一个按钮:

I am really struggling to figure out a way to do this. Say I implement a button very simply in a widget window:

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

我可以使用 self.button.move(x,y) 在父小部件的区域周围移动它的初始化点,并且我可以从 mousePressEvent(self, e)<获取鼠标事件/code> 通过 ex()ey(),这样按钮就会移动到我点击的任何地方,但我似乎无法将所有这些放在一起拖动和删除框架.

I can move its initialization point around the parent widget's area using self.button.move(x,y), and I can get mouse events from mousePressEvent(self, e) via e.x() and e.y(), so that the button moves to wherever I click, but I just cannot seem to put all this together into a drag and drop framework.

澄清:在阅读了拖放的真正"含义后,这不是我需要的.我只是希望能够用我的鼠标移动小部件,这与您在冰箱上移动磁铁的方式非常相似.

Clarification: After reading on the 'true' meaning of Drag/Drop, that's not what I need. I just want to be able to move a widget around with my mouse, much similar to the way you move magnets on a fridge.

推荐答案

下面是一个仍然支持正常点击信号的可移动按钮的例子:

Here is an example of a moveable button that still supports the normal click signal properly:

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 中,我记录了初始开始位置和将在整个拖动过程中更新的位置.

In the mousePressEvent I record both the initial start position, and a position that will get updated throughout the drag.

mouseMoveEvent 中,我获得了小部件从点击位置到实际原点位置的正确偏移量,以便移动准确.

In the mouseMoveEvent, I get the proper offset of the widget from where it was clicked to where the actual origin is, so that the move is accurate.

mouseReleaseEvent 中,我检查整体移动是否大于至少一小部分.如果是,那么它是一个拖拽,我们忽略正常事件以不产生点击"信号.否则,我们允许正常的事件处理程序产生点击.

In the mouseReleaseEvent, I check to see if the overall move was greater than at least a tiny amount. If it was, then it was a drag and we ignore the normal event to not produce a "clicked" signal. Otherwise, we allow the normal event handler to produce the click.

这篇关于在 PyQt 中拖动/移动 QPushButton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆