PyQt4 - 拖放

Man*_*noj 9 python qt drag-and-drop button pyqt4

嘿,我一直在阅读本教程,了解PyQt4中的拖放方法.但是我无法理解以下几点.如果somepne可以让我更清楚,那就太好了.

 def mouseMoveEvent(self, e): //class Button


    mimeData = QtCore.QMimeData()

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

    dropAction = drag.start(QtCore.Qt.MoveAction)

def dropEvent(self, e): //class Example

    position = e.pos()
    self.button.move(position)

    e.setDropAction(QtCore.Qt.MoveAction)
    e.accept()
Run Code Online (Sandbox Code Playgroud)

为什么有一个单独的self.button.move()和e.setDropAction()不是self.button.move()实际上移动按钮本身?有人可以解释一下drag.setHotSpot和drag.start()的作用吗?谢谢.

Ava*_*ris 16

该教程严重过时.QDrag.startQt 4.3以来已经过时了.QDrag.exec_应该用来代替.

正如您从文档中看到的那样exec,它具有返回值.setDropActionin dropEvent确定此值.它没有执行此举.这就是为什么你需要self.button.move()做一个真正的移动.那么,有什么意义setDropAction呢?您可能需要知道您执行的拖动操作类型.想象一下,您正在两个列表小部件之间实现拖放.如果您执行了移动操作,则意味着您需要从源窗口小部件中删除该项目并在目标中创建一个项目.如果是复制操作,您可以保留原始文件并在目标中创建副本.

setHotSpot/ hotSpotsetPixmapa有关QDrag.您可以QPixmap在拖动项目时显示.hotSpot确定像素图的定位.像素图将被定位成使得光标将hotSpot相对于像素图的左上角.因此,在该教程的情况下,它是没有意义的,因为没有像素图显示.

以下是该教程的一些修改和更新版本.希望我收到足够的评论.你可以移动使用Right-Click复制Shift + Right-Click:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
from PyQt4 import QtGui, QtCore


class Button(QtGui.QPushButton):
    def mouseMoveEvent(self, e):
        if e.buttons() != QtCore.Qt.RightButton:
            return

        # write the relative cursor position to mime data
        mimeData = QtCore.QMimeData()
        # simple string with 'x,y'
        mimeData.setText('%d,%d' % (e.x(), e.y()))

        # let's make it fancy. we'll show a "ghost" of the button as we drag
        # grab the button to a pixmap
        pixmap = QtGui.QPixmap.grabWidget(self)

        # below makes the pixmap half transparent
        painter = QtGui.QPainter(pixmap)
        painter.setCompositionMode(painter.CompositionMode_DestinationIn)
        painter.fillRect(pixmap.rect(), QtGui.QColor(0, 0, 0, 127))
        painter.end()

        # make a QDrag
        drag = QtGui.QDrag(self)
        # put our MimeData
        drag.setMimeData(mimeData)
        # set its Pixmap
        drag.setPixmap(pixmap)
        # shift the Pixmap so that it coincides with the cursor position
        drag.setHotSpot(e.pos())

        # start the drag operation
        # exec_ will return the accepted action from dropEvent
        if drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction) == QtCore.Qt.MoveAction:
            print 'moved'
        else:
            print 'copied'


    def mousePressEvent(self, e):
        QtGui.QPushButton.mousePressEvent(self, e)
        if e.button() == QtCore.Qt.LeftButton:
            print 'press'



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


    def initUI(self):
        self.setAcceptDrops(True)

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

        self.buttons = [button]

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


    def dragEnterEvent(self, e):
        e.accept()


    def dropEvent(self, e):
        # get the relative position from the mime data
        mime = e.mimeData().text()
        x, y = map(int, mime.split(','))

        if e.keyboardModifiers() & QtCore.Qt.ShiftModifier:
            # copy
            # so create a new button
            button = Button('Button', self)
            # move it to the position adjusted with the cursor position at drag
            button.move(e.pos()-QtCore.QPoint(x, y))
            # show it
            button.show()
            # store it
            self.buttons.append(button)
            # set the drop action as Copy
            e.setDropAction(QtCore.Qt.CopyAction)
        else:
            # move
            # so move the dragged button (i.e. event.source())
            e.source().move(e.pos()-QtCore.QPoint(x, y))
            # set the drop action as Move
            e.setDropAction(QtCore.Qt.MoveAction)
        # tell the QDrag we accepted it
        e.accept()



if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    app.exec_()  
Run Code Online (Sandbox Code Playgroud)