PyQt4中 - 拖放 [英] PyQt4 - Drag and Drop
问题描述
嘿,我已经经历此教程对于理解PyQt4中拖放的方法。但是我不能够理解以下几点。这将是很好,如果能somepne使它更清楚我。
Hey I had been going through this tutorial for understanding drag and drop methods in PyQt4. However I am not able to understand the following points . It would be nice if somepne could make it clearer to me.
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()
为什么有一个单独的self.button.move()和e.setDropAction()犯规self.button.move()实际移动按钮本身?而可能有人解释什么drag.setHotSpot和drag.start()呢?谢谢你。
Why is there are a seperate self.button.move() and e.setDropAction() Doesnt self.button.move() actually move the button itself? And could someone explain what drag.setHotSpot and drag.start() do? Thanks.
推荐答案
这教程是严重过时。 QDrag.start
已经过时了,因为的Qt 4.3 。 QDrag.exec _
应替代使用。
That tutorial is seriously outdated. QDrag.start
is obsolete since Qt 4.3. QDrag.exec_
should be used instead.
你可以从文档的 EXEC
看,它有一个返回值。 setDropAction
在 dropEvent
确定此值。它不执行移动。这就是为什么你需要一个 self.button.move()
做的实际移动。那么,什么是点一个 setDropAction
?你可能需要知道你做了什么样的拖动操作。想象一下,你正在实施两个列表小部件之间拖放。如果你做了一个移动操作,这意味着你需要从源部件删除该项目,并创建一个目标。如果这是一个复制操作,你可以离开原来的,只是创建目标副本。
As you can see from the docs for exec
, it has a return value. setDropAction
in dropEvent
determines this value. It doesn't perform the move. That's why you need a self.button.move()
to do the actual moving. So, what's the point of a setDropAction
? You might need to know what kind of drag operation you did. Imagine you're implementing drag-drop between two list widgets. If you did a move operation, that means you need to remove the item from the source widget and create one in the target. If it was a copy operation, you can leave the original and just create a copy in the target.
setHotSpot
/ 热点
是关系到 setPixmap
的 QDrag
。当您拖动项目可以显示的QPixmap
。 热点
确定像素图的定位。像素映像将被定位成使得光标将在热点
相对于所述像素图的左上角。这样,在该教程的情况下,它是相当无意义,因为没有要显示的像素映射
setHotSpot
/hotSpot
is related to the setPixmap
of a QDrag
. You can display a QPixmap
as you drag the item. hotSpot
determines the positioning of the pixmap. The pixmap will be positioned such that the cursor will be at hotSpot
relative to the top-left corner of the pixmap. So, in the case of that tutorial, it is rather pointless since there is no pixmap to be shown.
下面是有点修改和更新该教程的版本。但愿,我已经包含足够的注释。你可以的移动的有右键点击
或复制的有 Shift +鼠标右键点击
:
Here is a bit modified and updated version of that tutorial. Hopefully, I've included enough comments. You can move with Right-Click
or copy with 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_()
这篇关于PyQt4中 - 拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!