Pyside2如何获得鼠标位置?

问题描述 投票:3回答:1

我想在我的pyside2应用程序中获得鼠标位置。(而不是QCursor提供的桌面鼠标位置)我尝试了两种方式。贝娄是我的代码。

import sys
from PySide2 import QtGui, QtWidgets, QtCore


class Palette(QtWidgets.QGraphicsScene):
    def __init__(self, parent=None):
        super().__init__(parent)


    def mousePressEvent(self, event):
        print(event.pos()) # always return (0,0)
        print(QtWidgets.QWidget.mapToGlobal(QtCore.QPoint(0, 0))) #makes parameter type error
        print(QtWidgets.QWidget.mapToGlobal(QtWidgets.QWidget))  # makes  parameter type error
        print(QtWidgets.QWidget.mapToGlobal(QtWidgets.QWidget.pos()))  # makes parameter type error

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        palette = Palette(self)
        view = QtWidgets.QGraphicsView(palette, self)
        view.resize(500, 500)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.resize(500, 500)
    main_window.show()
    app.exec_()

我很想知道我怎么能得到我的鼠标...

python python-3.x qgraphicsview qgraphicsscene pyside2
1个回答
4
投票

根据我的理解,如果您点击窗口小部件中的任何位置,您希望获得窗口上的位置。

要解决这个问题,逻辑如下:

  • 获取与窗口小部件相关的鼠标位置
  • 将该位置转换为全局位置,即相对于屏幕。
  • 将该全局位置转换为相对于窗口的位置。

对于第一步,如果使用mousePressEvent()event.pos()将返回相对于小部件的位置。

对于第二步,您必须使用mapToGlobal()将相对于窗口小部件的位置转换为全局。

而对于第三步,使用了mapFromGlobal()的窗口。

def mousePressEvent(self, event):
    p = event.pos() # relative to widget
    gp = self.mapToGlobal(p) # relative to screen
    rw = self.window().mapFromGlobal(gp) # relative to window
    print("position relative to window: ", rw)
    super(Widget, self).mousePressEvent(event)

更新:

QGraphicsScene不是一个小部件,它不是一个视觉元素,虽然它是视觉元素表示的一部分:QGraphicsView。为了让你理解我会用一个类比来解释你,让我们说有一个摄像师记录一个场景,在这个例子中QGraphicsScene是场景,QGraphicsView是相机记录的,也就是说,它显示了一块QGraphicsScene ,所以可能有另一个摄像师从另一个点记录场景,所以它会从另一个角度显示相同的场景,所以场景的位置取决于摄像头,所以如果你当前的问题相当于说哪个是位置P点相对于摄像机的第i个,而且从场景中是不可能的,你应该从相机中获取它。

总而言之,您不应该使用QGraphicsScene而是使用QGraphicsView,以下解决方案使用两种不同的方法实现相同的逻辑:

1.创建QGraphicsView的自定义类:

import sys
from PySide2 import QtGui, QtWidgets, QtCore


class GraphicsView(QtWidgets.QGraphicsView):
    def mousePressEvent(self, event):
        p = event.pos() # relative to widget
        gp = self.mapToGlobal(p) # relative to screen
        rw = self.window().mapFromGlobal(gp) # relative to window
        print("position relative to window: ", rw)
        super(GraphicsView, self).mousePressEvent(event)

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        scene = QtWidgets.QGraphicsScene(self)
        view = GraphicsView(scene, self)
        self.setCentralWidget(view)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.resize(500, 500)
    main_window.show()
    sys.exit(app.exec_())

2.使用eventfilter:

import sys
from PySide2 import QtGui, QtWidgets, QtCore


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        scene = QtWidgets.QGraphicsScene(self)
        self._view = QtWidgets.QGraphicsView(scene, self)
        self.setCentralWidget(self._view)
        self._view.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self._view and event.type() == QtCore.QEvent.MouseButtonPress:
            p = event.pos() # relative to widget
            gp = self.mapToGlobal(p) # relative to screen
            rw = self.window().mapFromGlobal(gp) # relative to window
            print("position relative to window: ", rw)
        return super(MainWindow, self).eventFilter(obj, event)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.resize(500, 500)
    main_window.show()
    sys.exit(app.exec_())

另一方面,mapToGlobal()是一个必须由实例调用的方法,当你使用QtWidgets.QWidget.mapToGlobal()时没有实例,我的问题是,你有什么位置的小部件?关于self的位置,所以你必须使用self.mapToGlobal(),它适用于属于从QWidget继承为QGraphicsView的类的对象,但不适用于QGraphicsScene,因为它不继承自QWidget,它不是指示的小部件在上面的行。

© www.soinside.com 2019 - 2024. All rights reserved.