aboutsummaryrefslogtreecommitdiffstats
path: root/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py')
-rw-r--r--examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py287
1 files changed, 287 insertions, 0 deletions
diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py
new file mode 100644
index 000000000..a0d685f85
--- /dev/null
+++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+
+#############################################################################
+##
+## 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 PySide 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):
+ n = 0
+
+ def __init__(self):
+ super(ColorItem, self).__init__()
+
+ self.color = QtGui.QColor(QtCore.qrand() % 256, QtCore.qrand() % 256,
+ QtCore.qrand() % 256)
+
+ 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)
+
+ def boundingRect(self):
+ return QtCore.QRectF(-15.5, -15.5, 34, 34)
+
+ def paint(self, painter, option, widget):
+ painter.setPen(QtCore.Qt.NoPen)
+ painter.setBrush(QtCore.Qt.darkGray)
+ painter.drawEllipse(-12, -12, 30, 30)
+ painter.setPen(QtGui.QPen(QtCore.Qt.black, 1))
+ painter.setBrush(QtGui.QBrush(self.color))
+ painter.drawEllipse(-15, -15, 30, 30)
+
+ def mousePressEvent(self, event):
+ if event.button() != QtCore.Qt.LeftButton:
+ event.ignore()
+ return
+
+ self.setCursor(QtCore.Qt.ClosedHandCursor)
+
+ def mouseMoveEvent(self, event):
+ if QtCore.QLineF(QtCore.QPointF(event.screenPos()), QtCore.QPointF(event.buttonDownScreenPos(QtCore.Qt.LeftButton))).length() < QtWidgets.QApplication.startDragDistance():
+ return
+
+ drag = QtGui.QDrag(event.widget())
+ mime = QtCore.QMimeData()
+ drag.setMimeData(mime)
+
+ ColorItem.n += 1
+ if ColorItem.n > 2 and QtCore.qrand() % 3 == 0:
+ image = QtGui.QImage(':/images/head.png')
+ mime.setImageData(image)
+ drag.setPixmap(QtGui.QPixmap.fromImage(image).scaled(30,40))
+ drag.setHotSpot(QtCore.QPoint(15, 30))
+ else:
+ mime.setColorData(self.color)
+ mime.setText("#%02x%02x%02x" % (self.color.red(), self.color.green(), self.color.blue()))
+
+ pixmap = QtGui.QPixmap(34, 34)
+ pixmap.fill(QtCore.Qt.white)
+
+ painter = QtGui.QPainter(pixmap)
+ painter.translate(15, 15)
+ painter.setRenderHint(QtGui.QPainter.Antialiasing)
+ self.paint(painter, None, None)
+ painter.end()
+
+ pixmap.setMask(pixmap.createHeuristicMask())
+
+ drag.setPixmap(pixmap)
+ drag.setHotSpot(QtCore.QPoint(15, 20))
+
+ drag.exec_()
+ self.setCursor(QtCore.Qt.OpenHandCursor)
+
+ def mouseReleaseEvent(self, event):
+ self.setCursor(QtCore.Qt.OpenHandCursor)
+
+
+class RobotPart(QtWidgets.QGraphicsItem):
+ def __init__(self, parent=None):
+ super(RobotPart, self).__init__(parent)
+
+ self.color = QtGui.QColor(QtCore.Qt.lightGray)
+ self.pixmap = None
+ self.dragOver = False
+
+ self.setAcceptDrops(True)
+
+ def dragEnterEvent(self, event):
+ if event.mimeData().hasColor() or \
+ (isinstance(self, RobotHead) and event.mimeData().hasImage()):
+ event.setAccepted(True)
+ self.dragOver = True
+ self.update()
+ else:
+ event.setAccepted(False)
+
+ def dragLeaveEvent(self, event):
+ self.dragOver = False
+ self.update()
+
+ def dropEvent(self, event):
+ self.dragOver = False
+ if event.mimeData().hasColor():
+ self.color = QtGui.QColor(event.mimeData().colorData())
+ elif event.mimeData().hasImage():
+ self.pixmap = QtGui.QPixmap(event.mimeData().imageData())
+
+ self.update()
+
+
+class RobotHead(RobotPart):
+ def boundingRect(self):
+ return QtCore.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.drawEllipse(-7, -3 - 20, 7, 7)
+ painter.drawEllipse(0, -3 - 20, 7, 7)
+ painter.setBrush(QtCore.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.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)
+
+
+class RobotTorso(RobotPart):
+ def boundingRect(self):
+ return QtCore.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.drawEllipse(-25, -20, 20, 20)
+ painter.drawEllipse(5, -20, 20, 20)
+ painter.drawEllipse(-20, 22, 20, 20)
+ painter.drawEllipse(0, 22, 20, 20)
+
+
+class RobotLimb(RobotPart):
+ def boundingRect(self):
+ return QtCore.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.drawRoundedRect(self.boundingRect(), 50, 50,
+ QtCore.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()
+ 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 )
+ ]
+ self.animations = []
+ for item, pos_x, pos_y, rotation1, rotation2 in settings:
+ item.setPos(pos_x,pos_y)
+ animation = QtWidgets.QGraphicsItemAnimation()
+ animation.setItem(item)
+ animation.setTimeLine(self.timeline)
+ animation.setRotationAt(0, rotation1)
+ animation.setRotationAt(1, rotation2)
+ self.animations.append(animation)
+ self.animations[0].setScaleAt(1, 1.1, 1.1)
+
+ self.timeline.setUpdateInterval(1000 / 25)
+ self.timeline.setCurveShape(QtCore.QTimeLine.SineCurve)
+ self.timeline.setLoopCount(0)
+ self.timeline.setDuration(2000)
+ self.timeline.start()
+
+ def boundingRect(self):
+ return QtCore.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()))
+
+ scene = QtWidgets.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)
+ scene.addItem(item)
+
+ robot = Robot()
+ robot.setTransform(QtGui.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.setWindowTitle("Drag and Drop Robot")
+ view.show()
+
+ sys.exit(app.exec_())