使用拖放操作时如何拖动图标

时间:2019-03-15 20:50:02

标签: python pyqt5

当前,我具有以下代码,该代码执行拖放功能并通过拖放另一个按钮来生成新按钮。

但是我想知道的是: 拖动鼠标按钮时如何为他制作图像?

类似这样的东西:

enter image description here

这是您使用的代码

在这种情况下,我希望获得与先前显示的gif相同的效果,但使用Qpushbutton

from PyQt5.QtWidgets import QPushButton, QWidget, QApplication
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag
import sys

class Button(QPushButton):

    def __init__(self, title, parent):
        super().__init__(title, parent)


    def mouseMoveEvent(self, e):

        if e.buttons() != Qt.RightButton:
            return

        mimeData = QMimeData()

        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(e.pos() - self.rect().topLeft())

        dropAction = drag.exec_(Qt.MoveAction)


    def mousePressEvent(self, e):

        super().mousePressEvent(e)

        if e.button() == Qt.LeftButton:
            print('press')


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.setAcceptDrops(True)

        self.button = Button('Button', self)
        self.button.move(100, 65)

        self.setWindowTitle('Click or Move')
        self.setGeometry(300, 300, 280, 150)


    def dragEnterEvent(self, e):

        e.accept()


    def dropEvent(self, e):

        position = e.pos()
        self.button.move(position)
        self.create(position)
        e.setDropAction(Qt.MoveAction)
        e.accept()


    def create(self,position):
        print(position)
        self.position  = position
        self.newButton = QPushButton("new",self)
        self.newButton.move(self.position)
        self.newButton.resize(150,50)
        self.newButton.show()



if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    app.exec_() 

1 个答案:

答案 0 :(得分:1)

您必须使用grab()方法拍摄小部件图像,然后使用setPixmap()方法将其设置为QDrag。我还创建了一个方法,该方法创建具有相同q属性的源类型相同的小部件(这并不意味着它是小部件的副本,因为存在不可复制的元素)。另一方面,建议使用鼠标右键,因为鼠标左键会干扰点击的信号

from PyQt5 import QtCore, QtGui, QtWidgets

def fake_copy_widget(widget, parent):
    t = type(widget)
    w = t(parent)
    mo = widget.metaObject()
    for i in range(mo.propertyCount()):
        prop = mo.property(i)
        if prop.isWritable() and prop.isReadable():
            name = prop.name()
            w.setProperty(name, widget.property(name))
    return w

class Button(QtWidgets.QPushButton):
    def mouseMoveEvent(self, e):
        if e.buttons() & QtCore.Qt.RightButton:
            pos = self.mapFromGlobal(QtGui.QCursor().pos())
            ba = QtCore.QByteArray()
            ds = QtCore.QDataStream(ba, QtCore.QIODevice.WriteOnly)
            ds << pos
            mimeData = QtCore.QMimeData()
            mimeData.setData("application/x-pos", ba)
            pixmap = self.grab()
            drag = QtGui.QDrag(self)
            drag.setHotSpot(pos)
            drag.setPixmap(pixmap)
            drag.setMimeData(mimeData)
            drag.setHotSpot(e.pos() - self.rect().topLeft())
            dropAction = drag.exec_(QtCore.Qt.MoveAction)

class Example(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setAcceptDrops(True)
        button = Button('Button', self)
        button.move(100, 65)
        self.setWindowTitle('Click or Move')
        self.setGeometry(300, 300, 280, 150)

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat("application/x-pos"):
            e.accept()

    def dropEvent(self, e):
        position = e.pos()
        button = e.source()
        mimedata = e.mimeData()
        p = QtCore.QPoint()
        ba = mimedata.data("application/x-pos")
        ds = QtCore.QDataStream(ba)
        ds >> p
        self.create(QtCore.QRect(position - p, button.size()), button, self)
        e.accept()

    def create(self, geometry, widget, parent):
        button = fake_copy_widget(widget, parent)
        button.setGeometry(geometry)
        button.show()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())