[PYTHON] PyQt4 - 드래그 앤 드롭
PYTHONPyQt4 - 드래그 앤 드롭
이 튜토리얼을 통해 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()
왜 self.button.move와 e.setDropAction이 분리되어 있습니까? self.button.move ()가 실제로 버튼 자체를 움직이지 않습니까? 누군가 drag.setHotSpot과 drag.start ()가 무슨 일을하는지 설명 할 수 있습니까? 감사.
해결법
-
==============================
1.그 튜토리얼은 진부하게 오래된 것입니다. QDrag.start는 Qt 4.3부터 폐기되었습니다. 대신 QDrag.exec_를 사용해야합니다.
그 튜토리얼은 진부하게 오래된 것입니다. QDrag.start는 Qt 4.3부터 폐기되었습니다. 대신 QDrag.exec_를 사용해야합니다.
exec에 대한 문서에서 볼 수 있듯이 반환 값이 있습니다. dropEvent의 setDropAction가이 값을 결정합니다. 그것은 이동을 수행하지 않습니다. 그래서 실제 이동을하려면 self.button.move ()가 필요합니다. 그렇다면 setDropAction의 핵심은 무엇입니까? 당신이 한 드래그 작업의 종류를 알아야 할 수도 있습니다. 두 개의 목록 위젯간에 드래그 드롭을 구현한다고 가정 해보십시오. 이동 작업을 수행했다면, 소스 위젯에서 항목을 제거하고 대상에 항목을 만들어야 함을 의미합니다. 복사 작업 인 경우 원본을 그대로두고 대상에 복사본을 만들면됩니다.
setHotSpot / hotSpot은 QDrag의 setPixmap과 관련이 있습니다. 항목을 드래그 할 때 QPixmap을 표시 할 수 있습니다. hotSpot은 픽스맵의 위치를 결정합니다. pixmap은 커서가 pixmap의 왼쪽 상단 모서리를 기준으로 hotSpot에 위치하도록 배치됩니다. 따라서이 튜토리얼의 경우에는 표시 할 픽스맵이 없기 때문에 무의미합니다.
이 튜토리얼의 약간 수정되고 업데이트 된 버전이 있습니다. 바라기를, 나는 충분한 코멘트를 포함했다. 오른쪽 클릭으로 이동하거나 Shift + 오른쪽 클릭으로 복사 할 수 있습니다.
#!/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_()
-
==============================
2.PyQt5 및 Python 3에 맞게 수정 된 Avaris의 대답.
PyQt5 및 Python 3에 맞게 수정 된 Avaris의 대답.
#!/usr/bin/python # -*- coding: utf-8 -*- # Adapted for PyQt5 and Python 3 from Avaris' answer to # https://stackoverflow.com/questions/14395799/pyqt4-drag-and-drop import sys from PyQt5.QtWidgets import QPushButton, QWidget, QApplication from PyQt5.QtCore import Qt, QMimeData, QPoint from PyQt5.QtGui import QDrag, QPixmap, QPainter, QColor class Button(QPushButton): def mouseMoveEvent(self, e): if e.buttons() != Qt.RightButton: return # write the relative cursor position to mime data mimeData = 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 = QWidget.grab(self) # below makes the pixmap half transparent painter = QPainter(pixmap) painter.setCompositionMode(painter.CompositionMode_DestinationIn) painter.fillRect(pixmap.rect(), QColor(0, 0, 0, 127)) painter.end() # make a QDrag drag = 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_(Qt.CopyAction | Qt.MoveAction) == Qt.MoveAction: print('moved') else: print('copied') def mousePressEvent(self, e): QPushButton.mousePressEvent(self, e) if e.button() == Qt.LeftButton: print('press') class Example(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() & 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()-QPoint(x, y)) # show it button.show() # store it self.buttons.append(button) # set the drop action as Copy e.setDropAction(Qt.CopyAction) else: # move # so move the dragged button (i.e. event.source()) e.source().move(e.pos()-QPoint(x, y)) # set the drop action as Move e.setDropAction(Qt.MoveAction) # tell the QDrag we accepted it e.accept() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() ex.show() app.exec_()
from https://stackoverflow.com/questions/14395799/pyqt4-drag-and-drop by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Python 스크립트의 프로그램이 있는지 확인하십시오. (0) | 2018.11.10 |
---|---|
[PYTHON] 파이썬에서 같은 길이의 여러리스트끼리 끼워 넣기 (0) | 2018.11.10 |
[PYTHON] OpenCV + Python-2.7을 사용하여 전신 탐지 및 추적 (0) | 2018.11.10 |
[PYTHON] Python 이미지 라이브러리에 Base64 문자열로드하기 (0) | 2018.11.10 |
[PYTHON] 파이썬 urllib / urllib2를 사용하여 파일을 업로드하는 http POST 요청을 작성하십시오. (0) | 2018.11.10 |