examples/widgets/draganddrop/draggabletext¶
(You can also check this code in the repository)
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
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/dictionary">
<file>words.txt</file>
</qresource>
</RCC>
# Copyright (C) 2013 Riverbank Computing Limited.
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
"""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 # noqa: F401
class DragLabel(QLabel):
def __init__(self, text, parent):
super().__init__(text, parent)
self.setAutoFillBackground(True)
self.setFrameShape(QFrame.Panel)
self.setFrameShadow(QFrame.Raised)
def mousePressEvent(self, event):
hot_spot = event.position().toPoint()
mime_data = QMimeData()
mime_data.setText(self.text())
hx = hot_spot.x()
hy = hot_spot.y()
mime_data.setData('application/x-hotspot', f'{hx} {hy}'.encode('utf-8'))
pixmap = QPixmap(self.size())
self.render(pixmap)
drag = QDrag(self)
drag.setMimeData(mime_data)
drag.setPixmap(pixmap)
drag.setHotSpot(hot_spot)
drop_action = drag.exec(Qt.CopyAction | Qt.MoveAction, Qt.CopyAction)
if drop_action == Qt.MoveAction:
self.close()
self.update()
class DragWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
dictionary_file = QFile(':/dictionary/words.txt')
dictionary_file.open(QIODevice.ReadOnly)
x = 5
y = 5
for word in QTextStream(dictionary_file).readAll().split():
word_label = DragLabel(word, self)
word_label.move(x, y)
word_label.show()
x += word_label.width() + 2
if x >= 195:
x = 5
y += word_label.height() + 2
new_palette = self.palette()
new_palette.setColor(QPalette.Window, Qt.white)
self.setPalette(new_palette)
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.position().toPoint()
hot_spot = QPoint()
hot_spot_pos = mime.data('application/x-hotspot').split(' ')
if len(hot_spot_pos) == 2:
hot_spot.setX(hot_spot_pos[0].toInt()[0])
hot_spot.setY(hot_spot_pos[1].toInt()[0])
for piece in pieces:
new_label = DragLabel(piece, self)
new_label.move(position - hot_spot)
new_label.show()
position += QPoint(new_label.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())