diff options
Diffstat (limited to 'examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py')
-rw-r--r-- | examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py | 279 |
1 files changed, 123 insertions, 156 deletions
diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py index 68a54d552..9ed92b26e 100644 --- a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py +++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py @@ -1,188 +1,160 @@ +# Copyright (C) 2013 Riverbank Computing Limited. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -############################################################################# -## -## Copyright (C) 2013 Riverbank Computing Limited. -## Copyright (C) 2016 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 PySide2 import QtCore, QtGui, QtWidgets - -import dragdroprobot_rc - - -class ColorItem(QtWidgets.QGraphicsItem): +import sys +import math + +from PySide6.QtCore import (QEasingCurve, QLineF, QMimeData, QPoint, QPointF, + QRandomGenerator, QRectF, QTimeLine, Qt) +from PySide6.QtGui import (QBrush, QColor, QDrag, QImage, QPainter, QPixmap, + QPen, QTransform) +from PySide6.QtWidgets import (QApplication, QGraphicsItem, + QGraphicsItemAnimation, QGraphicsScene, + QGraphicsView) + +import dragdroprobot_rc # noqa: F401 + + +def random(boundary): + return QRandomGenerator.global_().bounded(boundary) + + +class ColorItem(QGraphicsItem): n = 0 def __init__(self): - super(ColorItem, self).__init__() + super().__init__() - self.color = QtGui.QColor(QtCore.qrand() % 256, QtCore.qrand() % 256, - QtCore.qrand() % 256) + self.color = QColor(random(256), random(256), random(256)) + (r, g, b) = (self.color.red(), self.color.green(), self.color.blue()) self.setToolTip( - "QColor(%d, %d, %d)\nClick and drag this color onto the robot!" % - (self.color.red(), self.color.green(), self.color.blue()) - ) - self.setCursor(QtCore.Qt.OpenHandCursor) + f"QColor({r}, {g}, {b})\nClick and drag this color onto the robot!") + self.setCursor(Qt.OpenHandCursor) + self._start_drag_distance = QApplication.startDragDistance() def boundingRect(self): - return QtCore.QRectF(-15.5, -15.5, 34, 34) + return QRectF(-15.5, -15.5, 34, 34) def paint(self, painter, option, widget): - painter.setPen(QtCore.Qt.NoPen) - painter.setBrush(QtCore.Qt.darkGray) + painter.setPen(Qt.NoPen) + painter.setBrush(Qt.darkGray) painter.drawEllipse(-12, -12, 30, 30) - painter.setPen(QtGui.QPen(QtCore.Qt.black, 1)) - painter.setBrush(QtGui.QBrush(self.color)) + painter.setPen(QPen(Qt.black, 1)) + painter.setBrush(QBrush(self.color)) painter.drawEllipse(-15, -15, 30, 30) def mousePressEvent(self, event): - if event.button() != QtCore.Qt.LeftButton: + if event.button() != Qt.LeftButton: event.ignore() return - self.setCursor(QtCore.Qt.ClosedHandCursor) + self.setCursor(Qt.ClosedHandCursor) def mouseMoveEvent(self, event): - if QtCore.QLineF(QtCore.QPointF(event.screenPos()), QtCore.QPointF(event.buttonDownScreenPos(QtCore.Qt.LeftButton))).length() < QtWidgets.QApplication.startDragDistance(): + start = QPointF(event.buttonDownScreenPos(Qt.LeftButton)) + if QLineF(event.screenPos(), start).length() < self._start_drag_distance: return - drag = QtGui.QDrag(event.widget()) - mime = QtCore.QMimeData() + drag = QDrag(event.widget()) + mime = QMimeData() drag.setMimeData(mime) ColorItem.n += 1 - if ColorItem.n > 2 and QtCore.qrand() % 3 == 0: - image = QtGui.QImage(':/images/head.png') + if ColorItem.n > 2 and random(3) == 0: + image = QImage(':/images/head.png') mime.setImageData(image) - drag.setPixmap(QtGui.QPixmap.fromImage(image).scaled(30,40)) - drag.setHotSpot(QtCore.QPoint(15, 30)) + drag.setPixmap(QPixmap.fromImage(image).scaled(30, 40)) + drag.setHotSpot(QPoint(15, 30)) else: mime.setColorData(self.color) - mime.setText("#%02x%02x%02x" % (self.color.red(), self.color.green(), self.color.blue())) + (r, g, b) = (self.color.red(), self.color.green(), self.color.blue()) + mime.setText(f"#{r:02x}{g:02x}{b:02x}") - pixmap = QtGui.QPixmap(34, 34) - pixmap.fill(QtCore.Qt.white) + pixmap = QPixmap(34, 34) + pixmap.fill(Qt.white) - painter = QtGui.QPainter(pixmap) - painter.translate(15, 15) - painter.setRenderHint(QtGui.QPainter.Antialiasing) - self.paint(painter, None, None) - painter.end() + with QPainter(pixmap) as painter: + painter.translate(15, 15) + painter.setRenderHint(QPainter.Antialiasing) + self.paint(painter, None, None) pixmap.setMask(pixmap.createHeuristicMask()) drag.setPixmap(pixmap) - drag.setHotSpot(QtCore.QPoint(15, 20)) + drag.setHotSpot(QPoint(15, 20)) - drag.exec_() - self.setCursor(QtCore.Qt.OpenHandCursor) + drag.exec() + self.setCursor(Qt.OpenHandCursor) def mouseReleaseEvent(self, event): - self.setCursor(QtCore.Qt.OpenHandCursor) + self.setCursor(Qt.OpenHandCursor) -class RobotPart(QtWidgets.QGraphicsItem): +class RobotPart(QGraphicsItem): def __init__(self, parent=None): - super(RobotPart, self).__init__(parent) + super().__init__(parent) - self.color = QtGui.QColor(QtCore.Qt.lightGray) + self.color = QColor(Qt.lightGray) self.pixmap = None - self.dragOver = False + self._drag_over = False self.setAcceptDrops(True) def dragEnterEvent(self, event): - if event.mimeData().hasColor() or \ - (isinstance(self, RobotHead) and event.mimeData().hasImage()): + if (event.mimeData().hasColor() + or (isinstance(self, RobotHead) and event.mimeData().hasImage())): event.setAccepted(True) - self.dragOver = True + self._drag_over = True self.update() else: event.setAccepted(False) def dragLeaveEvent(self, event): - self.dragOver = False + self._drag_over = False self.update() def dropEvent(self, event): - self.dragOver = False + self._drag_over = False if event.mimeData().hasColor(): - self.color = QtGui.QColor(event.mimeData().colorData()) + self.color = QColor(event.mimeData().colorData()) elif event.mimeData().hasImage(): - self.pixmap = QtGui.QPixmap(event.mimeData().imageData()) + self.pixmap = QPixmap(event.mimeData().imageData()) self.update() class RobotHead(RobotPart): def boundingRect(self): - return QtCore.QRectF(-15, -50, 30, 50) + return QRectF(-15, -50, 30, 50) def paint(self, painter, option, widget=None): if not self.pixmap: - painter.setBrush(self.dragOver and self.color.lighter(130) - or self.color) - painter.drawRoundedRect(-10, -30, 20, 30, 25, 25, - QtCore.Qt.RelativeSize) - painter.setBrush(QtCore.Qt.white) + painter.setBrush(self._drag_over and self.color.lighter(130) or self.color) + painter.drawRoundedRect(-10, -30, 20, 30, 25, 25, Qt.RelativeSize) + painter.setBrush(Qt.white) painter.drawEllipse(-7, -3 - 20, 7, 7) painter.drawEllipse(0, -3 - 20, 7, 7) - painter.setBrush(QtCore.Qt.black) + painter.setBrush(Qt.black) painter.drawEllipse(-5, -1 - 20, 2, 2) painter.drawEllipse(2, -1 - 20, 2, 2) - painter.setPen(QtGui.QPen(QtCore.Qt.black, 2)) - painter.setBrush(QtCore.Qt.NoBrush) + painter.setPen(QPen(Qt.black, 2)) + painter.setBrush(Qt.NoBrush) painter.drawArc(-6, -2 - 20, 12, 15, 190 * 16, 160 * 16) else: painter.scale(.2272, .2824) - painter.drawPixmap(QtCore.QPointF(-15*4.4, -50*3.54), self.pixmap) + painter.drawPixmap(QPointF(-15 * 4.4, -50 * 3.54), self.pixmap) class RobotTorso(RobotPart): def boundingRect(self): - return QtCore.QRectF(-30, -20, 60, 60) + return QRectF(-30, -20, 60, 60) def paint(self, painter, option, widget=None): - painter.setBrush(self.dragOver and self.color.lighter(130) - or self.color) - painter.drawRoundedRect(-20, -20, 40, 60, 25, 25, - QtCore.Qt.RelativeSize) + painter.setBrush(self._drag_over and self.color.lighter(130) + or self.color) + painter.drawRoundedRect(-20, -20, 40, 60, 25, 25, Qt.RelativeSize) painter.drawEllipse(-25, -20, 20, 20) painter.drawEllipse(5, -20, 20, 20) painter.drawEllipse(-20, 22, 20, 20) @@ -191,49 +163,49 @@ class RobotTorso(RobotPart): class RobotLimb(RobotPart): def boundingRect(self): - return QtCore.QRectF(-5, -5, 40, 10) + return QRectF(-5, -5, 40, 10) def paint(self, painter, option, widget=None): - painter.setBrush(self.dragOver and self.color.lighter(130) or self.color) + painter.setBrush(self._drag_over and self.color.lighter(130) or self.color) painter.drawRoundedRect(self.boundingRect(), 50, 50, - QtCore.Qt.RelativeSize) + Qt.RelativeSize) painter.drawEllipse(-5, -5, 10, 10) class Robot(RobotPart): def __init__(self): - super(Robot, self).__init__() - - self.torsoItem = RobotTorso(self) - self.headItem = RobotHead(self.torsoItem) - self.upperLeftArmItem = RobotLimb(self.torsoItem) - self.lowerLeftArmItem = RobotLimb(self.upperLeftArmItem) - self.upperRightArmItem = RobotLimb(self.torsoItem) - self.lowerRightArmItem = RobotLimb(self.upperRightArmItem) - self.upperRightLegItem = RobotLimb(self.torsoItem) - self.lowerRightLegItem = RobotLimb(self.upperRightLegItem) - self.upperLeftLegItem = RobotLimb(self.torsoItem) - self.lowerLeftLegItem = RobotLimb(self.upperLeftLegItem) - - self.timeline = QtCore.QTimeLine() + super().__init__() + + self.torsoItem = RobotTorso(self) + self.headItem = RobotHead(self.torsoItem) + self.upperLeftArmItem = RobotLimb(self.torsoItem) + self.lowerLeftArmItem = RobotLimb(self.upperLeftArmItem) + self._upper_right_arm_item = RobotLimb(self.torsoItem) + self._lower_right_arm_item = RobotLimb(self._upper_right_arm_item) + self._upper_right_leg_item = RobotLimb(self.torsoItem) + self._lower_right_leg_item = RobotLimb(self._upper_right_leg_item) + self.upperLeftLegItem = RobotLimb(self.torsoItem) + self.lowerLeftLegItem = RobotLimb(self.upperLeftLegItem) + + self.timeline = QTimeLine() settings = [ - # item position rotation at - # x y time 0 / 1 - ( self.headItem, 0, -18, 20, -20 ), - ( self.upperLeftArmItem, -15, -10, 190, 180 ), - ( self.lowerLeftArmItem, 30, 0, 50, 10 ), - ( self.upperRightArmItem, 15, -10, 300, 310 ), - ( self.lowerRightArmItem, 30, 0, 0, -70 ), - ( self.upperRightLegItem, 10, 32, 40, 120 ), - ( self.lowerRightLegItem, 30, 0, 10, 50 ), - ( self.upperLeftLegItem, -10, 32, 150, 80 ), - ( self.lowerLeftLegItem, 30, 0, 70, 10 ), - ( self.torsoItem, 0, 0, 5, -20 ) + # item position rotation at + # x y time 0 / 1 + (self.headItem, 0, -18, 20, -20), # noqa: E241 + (self.upperLeftArmItem, -15, -10, 190, 180), # noqa: E241 + (self.lowerLeftArmItem, 30, 0, 50, 10), # noqa: E241 + (self._upper_right_arm_item, 15, -10, 300, 310), # noqa: E241 + (self._lower_right_arm_item, 30, 0, 0, -70), # noqa: E241 + (self._upper_right_leg_item, 10, 32, 40, 120), # noqa: E241 + (self._lower_right_leg_item, 30, 0, 10, 50), # noqa: E241 + (self.upperLeftLegItem, -10, 32, 150, 80), # noqa: E241 + (self.lowerLeftLegItem, 30, 0, 70, 10), # noqa: E241 + (self.torsoItem, 0, 0, 5, -20) # noqa: E241 ] self.animations = [] for item, pos_x, pos_y, rotation1, rotation2 in settings: - item.setPos(pos_x,pos_y) - animation = QtWidgets.QGraphicsItemAnimation() + item.setPos(pos_x, pos_y) + animation = QGraphicsItemAnimation() animation.setItem(item) animation.setTimeLine(self.timeline) animation.setRotationAt(0, rotation1) @@ -242,45 +214,40 @@ class Robot(RobotPart): self.animations[0].setScaleAt(1, 1.1, 1.1) self.timeline.setUpdateInterval(1000 / 25) - self.timeline.setCurveShape(QtCore.QTimeLine.SineCurve) + curve = QEasingCurve(QEasingCurve.SineCurve) + self.timeline.setEasingCurve(curve) self.timeline.setLoopCount(0) self.timeline.setDuration(2000) self.timeline.start() def boundingRect(self): - return QtCore.QRectF() + return QRectF() def paint(self, painter, option, widget=None): pass -if __name__== '__main__': - - import sys - import math - - app = QtWidgets.QApplication(sys.argv) - - QtCore.qsrand(QtCore.QTime(0, 0, 0).secsTo(QtCore.QTime.currentTime())) +if __name__ == '__main__': + app = QApplication(sys.argv) - scene = QtWidgets.QGraphicsScene(-200, -200, 400, 400) + scene = QGraphicsScene(-200, -200, 400, 400) for i in range(10): item = ColorItem() - angle = i*6.28 / 10.0 - item.setPos(math.sin(angle)*150, math.cos(angle)*150) + angle = i * 2.0 * math.pi / 10.0 + item.setPos(math.sin(angle) * 150, math.cos(angle) * 150) scene.addItem(item) robot = Robot() - robot.setTransform(QtGui.QTransform().scale(1.2, 1.2)) + robot.setTransform(QTransform().scale(1.2, 1.2)) robot.setPos(0, -20) scene.addItem(robot) - view = QtWidgets.QGraphicsView(scene) - view.setRenderHint(QtGui.QPainter.Antialiasing) - view.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate) - view.setBackgroundBrush(QtGui.QColor(230, 200, 167)) + view = QGraphicsView(scene) + view.setRenderHint(QPainter.Antialiasing) + view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate) + view.setBackgroundBrush(QColor(230, 200, 167)) view.setWindowTitle("Drag and Drop Robot") view.show() - sys.exit(app.exec_()) + sys.exit(app.exec()) |