PySide:让 SVG 图像跟随鼠标而无需拖放? [英] PySide: Have an SVG image follow mouse without drag and drop?

查看:70
本文介绍了PySide:让 SVG 图像跟随鼠标而无需拖放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 SVG 图像放置在另一个应用程序中最终将成为 QGroupBox 的位置.然后,在第一次单击 SVG 时,SVG粘"在鼠标上(就像在拖放过程中按住鼠标按钮一样).第二次点击将释放(放下")图像.

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.

我一直在阅读,但不太了解小部件、项目、场景和视图之间的性质/关系.我下面的代码可以正常工作,但不太正确.图像几乎主动避开鼠标.对于 PyQt/PySide 的非 C、非 C++ 初学者,是否有明确的解释?或者对我哪里出错有一个简单的解释?

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 邮件列表中的 Jukka 能够帮助我解决以下问题:

Jukka on the PySide mailing list was able to help me out with the following response:

你不必在QGraphicsView中做任何事情,你可以有mousePressEventImage 中打开和关闭浮动.这些事件获取 QGraphicsMouseEvents 作为参数,这些具有您需要的有关光标或鼠标按下位置的信息.所以,在简而言之,从 Viewport 中删除 mousePressEvent 并替换hoverMoveEvent 在你的 Image 中,它会起作用:

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)

这篇关于PySide:让 SVG 图像跟随鼠标而无需拖放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆