draggabletext_rc.py

# Resource object code (Python 3)
# Created by: object code
# Created by: The Resource Compiler for Qt version 5.14.0
# WARNING! All changes made in this file will be lost!

from PySide6 import QtCore

qt_resource_data = b"\
\x00\x00\x00\xf7\
Q\
t\x0aQuarterly\x0ais\x0aa\
\x0apaper\x0abased\x0anew\
sletter\x0aexclusiv\
ely\x0aavailable\x0ato\
\x0aQt\x0acustomers\x0aEv\
ery\x0aquarter\x0awe\x0am\
ail\x0aout\x0aan\x0aissue\
\x0athat\x0awe\x0ahope\x0awi\
ll\x0abring\x0aadded\x0ai\
nsight\x0aand\x0apleas\
ure\x0ato\x0ayour\x0aQt\x0ap\
rogramming\x0awith\x0a\
high\x0aquality\x0atec\
hnical\x0aarticles\x0a\
written\x0aby\x0aQt\x0aex\
perts\x0a\
"

qt_resource_name = b"\
\x00\x0a\
\x0b\x0b\x17\xd9\
\x00d\
\x00i\x00c\x00t\x00i\x00o\x00n\x00a\x00r\x00y\
\x00\x09\
\x08\xb6\xa74\
\x00w\
\x00o\x00r\x00d\x00s\x00.\x00t\x00x\x00t\
"

qt_resource_struct = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01e\xaf\x16\xd2\x9d\
"

def qInitResources():
    QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)

def qCleanupResources():
    QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)

qInitResources()

words.txt

Qt
Quarterly
is
a
paper
based
newsletter
exclusively
available
to
Qt
customers
Every
quarter
we
mail
out
an
issue
that
we
hope
will
bring
added
insight
and
pleasure
to
your
Qt
programming
with
high
quality
technical
articles
written
by
Qt
experts

draggabletext.qrc

<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/dictionary">
   <file>words.txt</file>
</qresource>
</RCC>

draggabletext.py

"""PySide6 port of the widgets/draganddrop/draggabletext example from Qt v5.x, originating from PyQt"""

from PySide6.QtCore import QFile, QIODevice, QMimeData, QPoint, Qt, QTextStream
from PySide6.QtGui import QDrag, QPalette, QPixmap
from PySide6.QtWidgets import QApplication, QFrame, QLabel, QWidget

import draggabletext_rc


class DragLabel(QLabel):
    def __init__(self, text, parent):
        super(DragLabel, self).__init__(text, parent)

        self.setAutoFillBackground(True)
        self.setFrameShape(QFrame.Panel)
        self.setFrameShadow(QFrame.Raised)

    def mousePressEvent(self, event):
        hotSpot = event.pos()

        mimeData = QMimeData()
        mimeData.setText(self.text())
        mimeData.setData('application/x-hotspot',
                b'%d %d' % (hotSpot.x(), hotSpot.y()))

        pixmap = QPixmap(self.size())
        self.render(pixmap)

        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setPixmap(pixmap)
        drag.setHotSpot(hotSpot)

        dropAction = drag.exec_(Qt.CopyAction | Qt.MoveAction, Qt.CopyAction)

        if dropAction == Qt.MoveAction:
            self.close()
            self.update()


class DragWidget(QWidget):
    def __init__(self, parent=None):
        super(DragWidget, self).__init__(parent)

        dictionaryFile = QFile(':/dictionary/words.txt')
        dictionaryFile.open(QIODevice.ReadOnly)

        x = 5
        y = 5

        for word in QTextStream(dictionaryFile).readAll().split():
            wordLabel = DragLabel(word, self)
            wordLabel.move(x, y)
            wordLabel.show()
            x += wordLabel.width() + 2
            if x >= 195:
                x = 5
                y += wordLabel.height() + 2

        newPalette = self.palette()
        newPalette.setColor(QPalette.Window, Qt.white)
        self.setPalette(newPalette)

        self.setAcceptDrops(True)
        self.setMinimumSize(400, max(200, y))
        self.setWindowTitle("Draggable Text")

    def dragEnterEvent(self, event):
        if event.mimeData().hasText():
            if event.source() in self.children():
                event.setDropAction(Qt.MoveAction)
                event.accept()
            else:
                event.acceptProposedAction()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasText():
            mime = event.mimeData()
            pieces = mime.text().split()
            position = event.pos()
            hotSpot = QPoint()

            hotSpotPos = mime.data('application/x-hotspot').split(' ')
            if len(hotSpotPos) == 2:
               hotSpot.setX(hotSpotPos[0].toInt()[0])
               hotSpot.setY(hotSpotPos[1].toInt()[0])

            for piece in pieces:
                newLabel = DragLabel(piece, self)
                newLabel.move(position - hotSpot)
                newLabel.show()

                position += QPoint(newLabel.width(), 0)

            if event.source() in self.children():
                event.setDropAction(Qt.MoveAction)
                event.accept()
            else:
                event.acceptProposedAction()
        else:
            event.ignore()


if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)
    window = DragWidget()
    window.show()
    sys.exit(app.exec_())