[PySide] SVG image follow mouse w/o drag and drop?
Kevin Cole
dc.loco at gmail.com
Fri Aug 5 15:57:57 CEST 2016
Hi,
I'm trying to understand graphics items, scenes, views, widgets, and
not doing so well. I posted a question over on Stack Overflow, but
probably should have tried here first.
The question, copied below, is from
http://stackoverflow.com/questions/38749882/pyside-have-an-svg-image-follow-mouse-without-drag-and-drop
I'm trying to place an SVG image in what will eventually be a
QGroupBox in another application. Then, upon the first click over the
SVG, the SVG "sticks" to the mouse (as if the mouse button was held
down during a drag and drop). A second click will release ("drop") the
image.
I've been reading but not quite understanding the nature of /
relationship between Widgets, Items, Scenes and Views. My code below
sort of works but isn't quite right. The image almost actively avoids
the mouse. Is there a clear explanation somewhere for non-C, non-C++,
beginners with PyQt / PySide? Or is there a simple explanation for
where I've gone wrong?
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtSvg import *
class Image(QGraphicsSvgItem):
def __init__(self, parent=None):
super(Image, self).__init__("image.svg", parent)
self.parent = parent
self.setFlags(QGraphicsItem.ItemIsSelectable |
QGraphicsItem.ItemIsMovable)
self.setAcceptsHoverEvents(True)
self.svgSize = self.renderer().defaultSize()
self.width = self.svgSize.width()
self.height = self.svgSize.height()
self.absolute = None # Image's absolute (global) position
self.mobile = 0 # Initially immobile
self.scene = None # Not in a scene yet
self.view = None # Not in a view yet
def hoverEnterEvent(self, event):
print "Enter"
def hoverLeaveEvent(self, event):
print "Leave"
def hoverMoveEvent(self, event):
print "Moving"
self.absolute = QCursor.pos()
if self.view:
relative = self.view.mapFromGlobal(self.absolute)
if self.mobile:
# self.setPos(relative)
self.setPos(self.absolute)
class Viewport(QGraphicsView):
def __init__(self, parent=None):
super(Viewport, self).__init__(parent)
self.scene = QGraphicsScene()
self.image = Image()
self.image.setPos(100, 100)
self.scene.addItem(self.image)
self.setScene(self.scene)
self.image.scene = self.scene
self.image.view = self
def mousePressEvent(self, event):
super(Viewport, self).mousePressEvent(event)
self.image.mobile = (self.image.mobile + 1) % 2 # Toggle mobility
x = self.image.x() # + int(self.image.width / 2)
y = self.image.y() # + int(self.image.height / 2)
QCursor.setPos(x, y)
relative = self.mapFromGlobal(self.image.absolute)
print "absolute.x() = {0} absolute.y() = {1}"\
.format(self.image.absolute.x(), self.image.absolute.y())
print "relative.x() = {0} relative.y() = {1}"\
.format(relative.x(), relative.y())
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.view = Viewport(self)
hbox = QHBoxLayout()
hbox.addWidget(self.view)
self.setLayout(hbox)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
More information about the PySide
mailing list