From 45a0645901a839a1472588a3cbda4fd290cc556a Mon Sep 17 00:00:00 2001 From: Jaime Resano Date: Sun, 17 Oct 2021 23:54:04 +0200 Subject: Add dragable icons example Ported from c++. Pick-to: 6.2 Task-number: PYSIDE-841 Change-Id: Ie7fc583913727ecf1838bc31b79da3ccc293fea2 Reviewed-by: Friedemann Kleint Reviewed-by: Cristian Maureira-Fredes --- .../draggableicons/doc/draggableicons.png | Bin 0 -> 21766 bytes .../draggableicons/doc/draggableicons.rst | 9 ++ .../draganddrop/draggableicons/draggableicons.py | 167 +++++++++++++++++++++ .../draganddrop/draggableicons/draggableicons.qrc | 7 + .../draganddrop/draggableicons/images/boat.png | Bin 0 -> 2772 bytes .../draganddrop/draggableicons/images/car.png | Bin 0 -> 2963 bytes .../draganddrop/draggableicons/images/house.png | Bin 0 -> 3292 bytes 7 files changed, 183 insertions(+) create mode 100644 examples/widgets/draganddrop/draggableicons/doc/draggableicons.png create mode 100644 examples/widgets/draganddrop/draggableicons/doc/draggableicons.rst create mode 100644 examples/widgets/draganddrop/draggableicons/draggableicons.py create mode 100644 examples/widgets/draganddrop/draggableicons/draggableicons.qrc create mode 100644 examples/widgets/draganddrop/draggableicons/images/boat.png create mode 100644 examples/widgets/draganddrop/draggableicons/images/car.png create mode 100644 examples/widgets/draganddrop/draggableicons/images/house.png (limited to 'examples/widgets') diff --git a/examples/widgets/draganddrop/draggableicons/doc/draggableicons.png b/examples/widgets/draganddrop/draggableicons/doc/draggableicons.png new file mode 100644 index 000000000..640a99e44 Binary files /dev/null and b/examples/widgets/draganddrop/draggableicons/doc/draggableicons.png differ diff --git a/examples/widgets/draganddrop/draggableicons/doc/draggableicons.rst b/examples/widgets/draganddrop/draggableicons/doc/draggableicons.rst new file mode 100644 index 000000000..3f67e5809 --- /dev/null +++ b/examples/widgets/draganddrop/draggableicons/doc/draggableicons.rst @@ -0,0 +1,9 @@ +Draggable Icons Example +======================= + +The Draggable Icons example shows how to drag and drop image data between +widgets in the same application,and between different applications. + +.. image:: draggableicons.png + :width: 536 + :alt: draggable icons screenshot diff --git a/examples/widgets/draganddrop/draggableicons/draggableicons.py b/examples/widgets/draganddrop/draggableicons/draggableicons.py new file mode 100644 index 000000000..f8411de2e --- /dev/null +++ b/examples/widgets/draganddrop/draggableicons/draggableicons.py @@ -0,0 +1,167 @@ +############################################################################# +## +## Copyright (C) 2021 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from pathlib import Path +import sys + +from PySide6.QtCore import QByteArray, QDataStream, QIODevice, QMimeData, QPoint, Qt +from PySide6.QtGui import QColor, QDrag, QPainter, QPixmap +from PySide6.QtWidgets import QApplication, QFrame, QHBoxLayout, QLabel, QWidget + + +class DragWidget(QFrame): + def __init__(self, parent: QWidget): + super().__init__(parent) + self.setMinimumSize(200, 200) + self.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel) + self.setAcceptDrops(True) + + path = Path(__file__).resolve().parent + + boat_icon = QLabel(self) + boat_icon.setPixmap(QPixmap(path / "images" / "boat.png")) + boat_icon.move(10, 10) + boat_icon.show() + boat_icon.setAttribute(Qt.WA_DeleteOnClose) + + car_icon = QLabel(self) + car_icon.setPixmap(QPixmap(path / "images" / "car.png")) + car_icon.move(100, 10) + car_icon.show() + car_icon.setAttribute(Qt.WA_DeleteOnClose) + + house_icon = QLabel(self) + house_icon.setPixmap(QPixmap(path / "images" / "house.png")) + house_icon.move(10, 80) + house_icon.show() + house_icon.setAttribute(Qt.WA_DeleteOnClose) + + def dragEnterEvent(self, event): + if event.mimeData().hasFormat("application/x-dnditem_data"): + if event.source() == self: + event.setDropAction(Qt.MoveAction) + event.accept() + else: + event.acceptProposedAction() + else: + event.ignore() + + def dragMoveEvent(self, event): + if event.mimeData().hasFormat("application/x-dnditem_data"): + if event.source() == self: + event.setDropAction(Qt.MoveAction) + event.accept() + else: + event.acceptProposedAction() + else: + event.ignore() + + def dropEvent(self, event): + if event.mimeData().hasFormat("application/x-dnditem_data"): + item_data: QByteArray = event.mimeData().data("application/x-dnditem_data") + data_stream = QDataStream(item_data, QIODevice.ReadOnly) + + pixmap = QPixmap() + offset = QPoint() + + data_stream >> pixmap >> offset + + new_icon = QLabel(self) + new_icon.setPixmap(pixmap) + new_icon.move(event.position().toPoint() - offset) + new_icon.show() + new_icon.setAttribute(Qt.WA_DeleteOnClose) + + if event.source() == self: + event.setDropAction(Qt.MoveAction) + event.accept() + else: + event.acceptProposedAction() + else: + event.ignore() + + def mousePressEvent(self, event): + child: QLabel = self.childAt(event.position().toPoint()) + if not child: + return + + pixmap = child.pixmap() + + item_data = QByteArray() + data_stream = QDataStream(item_data, QIODevice.WriteOnly) + + data_stream << pixmap << QPoint(event.position().toPoint() - child.pos()) + + mime_data = QMimeData() + mime_data.setData("application/x-dnditem_data", item_data) + + drag = QDrag(self) + drag.setMimeData(mime_data) + drag.setPixmap(pixmap) + drag.setHotSpot(event.position().toPoint() - child.pos()) + + # .copy() is important: python is different than c++ in this case + temp_pixmap = pixmap.copy() + painter = QPainter() + painter.begin(temp_pixmap) + painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127)) + painter.end() + + child.setPixmap(temp_pixmap) + + if drag.exec(Qt.CopyAction | Qt.MoveAction, Qt.CopyAction) == Qt.MoveAction: + child.close() + else: + child.show() + child.setPixmap(pixmap) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + + main_widget = QWidget() + horizontal_layout = QHBoxLayout(main_widget) + horizontal_layout.addWidget(DragWidget(main_widget)) + horizontal_layout.addWidget(DragWidget(main_widget)) + + main_widget.setWindowTitle("Draggable Icons") + main_widget.show() + + sys.exit(app.exec()) diff --git a/examples/widgets/draganddrop/draggableicons/draggableicons.qrc b/examples/widgets/draganddrop/draggableicons/draggableicons.qrc new file mode 100644 index 000000000..63f84ac06 --- /dev/null +++ b/examples/widgets/draganddrop/draggableicons/draggableicons.qrc @@ -0,0 +1,7 @@ + + + images/boat.png + images/car.png + images/house.png + + diff --git a/examples/widgets/draganddrop/draggableicons/images/boat.png b/examples/widgets/draganddrop/draggableicons/images/boat.png new file mode 100644 index 000000000..46c894f06 Binary files /dev/null and b/examples/widgets/draganddrop/draggableicons/images/boat.png differ diff --git a/examples/widgets/draganddrop/draggableicons/images/car.png b/examples/widgets/draganddrop/draggableicons/images/car.png new file mode 100644 index 000000000..3cb35e56c Binary files /dev/null and b/examples/widgets/draganddrop/draggableicons/images/car.png differ diff --git a/examples/widgets/draganddrop/draggableicons/images/house.png b/examples/widgets/draganddrop/draggableicons/images/house.png new file mode 100644 index 000000000..ee9d5b115 Binary files /dev/null and b/examples/widgets/draganddrop/draggableicons/images/house.png differ -- cgit v1.2.3