Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''
- An elementary breadboard for experimenting with Qt's Drag'n'Drop classes.
- '''
- from PyQt5.QtCore import (
- Qt,
- QMimeData,
- QPoint,
- QTime
- )
- from PyQt5.QtGui import QDrag
- from PyQt5.QtWidgets import (
- QApplication,
- QHBoxLayout,
- QLabel,
- QMainWindow,
- QWidget
- )
- class SorcWidj(QLabel):
- '''A simple drag-source with ability
- to recognize the start of a drag motion
- and implement the drag.'''
- def __init__(self,text):
- super().__init__()
- self.setText(text)
- self.mouse_down = False # has a left-click happened yet?
- self.mouse_posn = QPoint() # if so, this was where...
- self.mouse_time = QTime() # ...and this was when.
- def mousePressEvent(self,event):
- if event.button() == Qt.LeftButton :
- self.mouse_down = True # we are left-clicked-upon
- self.mouse_posn = event.pos() # here and...
- self.mouse_time.start() # ...now
- event.ignore()
- super().mousePressEvent(event) # pass it on up
- def mouseReleaseEvent(self,event):
- # Mouse released in our rectangle, clear any drag info.
- self.mouse_down = False
- event.ignore()
- super().mouseReleaseEvent(event) # pass it on up
- def dragTargetChange(self, qob):
- # print signal from QDrag::targetChanged
- t = type(qob)
- print('target moved to',t)
- def doSomeDraggin(self):
- # Make a scaled pixmap of our widget to put under the cursor.
- thumb = self.grab().scaledToHeight(50)
- # Create the QDrag object and set its cursor over the pixmap
- dragster = QDrag(self)
- dragster.setPixmap(thumb)
- dragster.setHotSpot(QPoint(thumb.width()/2,thumb.height()/2))
- # Create some data to be dragged and load it in the dragster.
- md = QMimeData()
- md.setText(self.text())
- dragster.setMimeData(md)
- # Experiment: can we catch the target-change signal?
- dragster.targetChanged.connect(self.dragTargetChange)
- # Initiate the drag, which really is a form of modal dialog,
- # experimentally allowing any of the possible actions.
- # Result is supposed to be the action performed at the drop.
- act = dragster.exec_(Qt.MoveAction) # Qt.LinkAction Qt.CopyAction
- # Display the results of the drag.
- targ = dragster.target() # s.b. the widget that received the drop
- src = dragster.source() # s.b. this very widget
- print('action ',int(act),'target ',type(targ), 'source ',type(src))
- return
- def mouseMoveEvent(self,event):
- if self.mouse_down :
- # Mouse left-clicked and is now moving. Is this the start of a
- # drag? Note time since the click and approximate distance moved
- # since the click and test against the app's standard.
- t = self.mouse_time.elapsed()
- m = (event.pos() - self.mouse_posn).manhattanLength()
- if t >= QApplication.startDragTime() \
- or m >= QApplication.startDragDistance() :
- # Yes, a proper drag is indicated. Commence dragging.
- self.doSomeDraggin()
- event.accept()
- return
- # Move does not (yet) constitute a drag, ignore it.
- event.ignore()
- super().mouseMoveEvent(event)
- class TargWidj(QLabel):
- '''A simple class that can detect an incoming drag
- and accept it, but only if it's a Copy of plain text.'''
- def __init__(self,text):
- super().__init__()
- self.setAcceptDrops(True)
- self.setText(text)
- self.setStyleSheet('')
- def dragEnterEvent(self, event):
- print('drag enter')
- dbg = event.proposedAction()
- if (event.proposedAction() & Qt.CopyAction) \
- and (event.mimeData().hasFormat("text/plain")) :
- self.setStyleSheet('background: green;')
- event.acceptProposedAction()
- else:
- self.setStyleSheet('background: red;')
- def dragMoveEvent(self, event):
- print('drag moving')
- def dragLeaveEvent(self, event):
- print('drag leaving')
- self.setStyleSheet('')
- def dropEvent(self, event):
- print('dropping')
- self.setText( event.mimeData().text() )
- self.setStyleSheet('')
- def main():
- import sys
- app = QApplication(sys.argv)
- main = QMainWindow()
- central = QWidget()
- hbo = QHBoxLayout()
- hbo.addWidget( SorcWidj('Source Widget') )
- hbo.addWidget( TargWidj('Target') )
- central.setLayout(hbo)
- main.setCentralWidget( central )
- main.show()
- app.exec_()
- if __name__ == '__main__' :
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement