1#!/usr/bin/env python 2 3 4############################################################################# 5## 6## Copyright (C) 2013 Riverbank Computing Limited. 7## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 8## All rights reserved. 9## 10## This file is part of the examples of PyQt. 11## 12## $QT_BEGIN_LICENSE:BSD$ 13## You may use this file under the terms of the BSD license as follows: 14## 15## "Redistribution and use in source and binary forms, with or without 16## modification, are permitted provided that the following conditions are 17## met: 18## * Redistributions of source code must retain the above copyright 19## notice, this list of conditions and the following disclaimer. 20## * Redistributions in binary form must reproduce the above copyright 21## notice, this list of conditions and the following disclaimer in 22## the documentation and/or other materials provided with the 23## distribution. 24## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor 25## the names of its contributors may be used to endorse or promote 26## products derived from this software without specific prior written 27## permission. 28## 29## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 40## $QT_END_LICENSE$ 41## 42############################################################################# 43 44 45from PyQt5.QtCore import QFile, QIODevice, QMimeData, QPoint, Qt, QTextStream 46from PyQt5.QtGui import QDrag, QPalette, QPixmap 47from PyQt5.QtWidgets import QApplication, QFrame, QLabel, QWidget 48 49import draggabletext_rc 50 51 52class DragLabel(QLabel): 53 def __init__(self, text, parent): 54 super(DragLabel, self).__init__(text, parent) 55 56 self.setAutoFillBackground(True) 57 self.setFrameShape(QFrame.Panel) 58 self.setFrameShadow(QFrame.Raised) 59 60 def mousePressEvent(self, event): 61 hotSpot = event.pos() 62 63 mimeData = QMimeData() 64 mimeData.setText(self.text()) 65 mimeData.setData('application/x-hotspot', 66 '%d %d' % (hotSpot.x(), hotSpot.y())) 67 68 pixmap = QPixmap(self.size()) 69 self.render(pixmap) 70 71 drag = QDrag(self) 72 drag.setMimeData(mimeData) 73 drag.setPixmap(pixmap) 74 drag.setHotSpot(hotSpot) 75 76 dropAction = drag.exec_(Qt.CopyAction | Qt.MoveAction, Qt.CopyAction) 77 78 if dropAction == Qt.MoveAction: 79 self.close() 80 self.update() 81 82 83class DragWidget(QWidget): 84 def __init__(self, parent=None): 85 super(DragWidget, self).__init__(parent) 86 87 dictionaryFile = QFile(':/dictionary/words.txt') 88 dictionaryFile.open(QIODevice.ReadOnly) 89 90 x = 5 91 y = 5 92 93 for word in QTextStream(dictionaryFile).readAll().split(): 94 wordLabel = DragLabel(word, self) 95 wordLabel.move(x, y) 96 wordLabel.show() 97 x += wordLabel.width() + 2 98 if x >= 195: 99 x = 5 100 y += wordLabel.height() + 2 101 102 newPalette = self.palette() 103 newPalette.setColor(QPalette.Window, Qt.white) 104 self.setPalette(newPalette) 105 106 self.setAcceptDrops(True) 107 self.setMinimumSize(400, max(200, y)) 108 self.setWindowTitle("Draggable Text") 109 110 def dragEnterEvent(self, event): 111 if event.mimeData().hasText(): 112 if event.source() in self.children(): 113 event.setDropAction(Qt.MoveAction) 114 event.accept() 115 else: 116 event.acceptProposedAction() 117 else: 118 event.ignore() 119 120 def dropEvent(self, event): 121 if event.mimeData().hasText(): 122 mime = event.mimeData() 123 pieces = mime.text().split() 124 position = event.pos() 125 hotSpot = QPoint() 126 127 hotSpotPos = mime.data('application/x-hotspot').split(' ') 128 if len(hotSpotPos) == 2: 129 hotSpot.setX(hotSpotPos[0].toInt()[0]) 130 hotSpot.setY(hotSpotPos[1].toInt()[0]) 131 132 for piece in pieces: 133 newLabel = DragLabel(piece, self) 134 newLabel.move(position - hotSpot) 135 newLabel.show() 136 137 position += QPoint(newLabel.width(), 0) 138 139 if event.source() in self.children(): 140 event.setDropAction(Qt.MoveAction) 141 event.accept() 142 else: 143 event.acceptProposedAction() 144 else: 145 event.ignore() 146 147 148if __name__ == '__main__': 149 150 import sys 151 152 app = QApplication(sys.argv) 153 window = DragWidget() 154 window.show() 155 sys.exit(app.exec_()) 156