[PySide] SVG image follow mouse w/o drag and drop?

Purma Jukka jukka.purma at aalto.fi
Fri Aug 5 17:13:49 CEST 2016


Hi,

You don’t have to do anything in QGraphicsView, you can have mousePressEvent in Image to toggle floating on and off. These events get QGraphicsMouseEvents as parameters and these have the information you need about position of cursor or mouse press. So, in short, remove mousePressEvent from viewPort and replace hoverMoveEvent in your Image with this and it will work:     


    def hoverMoveEvent(self, event):
        if self.mobile:
            print("Moving")
            self.setPos(event.scenePos() - QPoint(self.width / 2, self.height / 2))

    def mousePressEvent(self, event):
        self.mobile = not self.mobile # Toggle mobility
        super().mousePressEvent(event)



Jukka

> Kevin Cole <dc.loco at gmail.com> kirjoitti 5.8.2016 kello 16.57:
> 
> 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_())
> _______________________________________________
> PySide mailing list
> PySide at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/pyside



More information about the PySide mailing list