简体   繁体   English

Pyside2如何获取鼠标位置?

[英]Pyside2 how to get mouse position?

I want to get mouse position in my pyside2 application.(not desktop mouse position that QCursor gives) and I tried two way.我想在我的 pyside2 应用程序中获取鼠标位置。(不是 QCursor 提供的桌面鼠标位置),我尝试了两种方法。 Bellow is my code.波纹管是我的代码。

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_()

I very wonder how i can get my mouse pos...我很想知道我怎样才能让我的鼠标位置...

From what I understand you want to get the position on the window if you click anywhere in a widget.据我了解,如果您单击小部件中的任意位置,您希望获得窗口上的位置。

To solve the problem, the logic is as follows:为了解决这个问题,逻辑如下:

  • Get the mouse position with respect to the widget获取鼠标相对于小部件的位置
  • Convert that position to a global position, that is, with respect to the screen.将该位置转换为全局位置,即相对于屏幕。
  • Convert that global position to a position relative to the window.将该全局位置转换为相对于窗口的位置。

For the first step if mousePressEvent() is used, event.pos() returns the position relative to the widget.对于第一步,如果使用mousePressEvent() ,则event.pos()返回相对于小部件的位置。

For the second step you must convert that position relative to the widget to global with mapToGlobal() .对于第二步,您必须使用mapToGlobal()将相对于小部件的位置转换为全局位置。

And for the third step mapFromGlobal() of window is used.第三步使用 window 的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)

Update:更新:

The QGraphicsScene is not a widget, it is not a visual element, although it is part of the representation of a visual element: the QGraphicsView . QGraphicsScene不是小部件,也不是可视元素,尽管它是可视元素表示的一部分: QGraphicsView For you to understand I will explain you with an analogy, let's say that there is a cameraman recording a scene, in that example the QGraphicsScene is the scene and the QGraphicsView is what the camera records, that is, it shows a piece of the QGraphicsScene , so there could be another cameraman recording the scene from another point, so it would show the same scene from another perspective, so the position of the scene depends on the camera, so if your current question would be equivalent to saying which is the position of the point P respect to the camera i-th, and that from the scene is impossible, you should get it from the camera.为了你理解我打个比方,假设有一个摄影师在录制一个场景,在那个例子中QGraphicsScene是场景, QGraphicsView是相机记录的,也就是说,它显示了QGraphicsScene ,所以可能会有另一个摄影师从另一个点记录场景,所以它会从另一个角度显示相同的场景,所以场景的位置取决于相机,所以如果你当前的问题相当于说哪个是位置点 P 相对于第 i 个相机,并且从场景中是不可能的,您应该从相机中获取它。

So in conclusion you should not use QGraphicsScene but QGraphicsView, the following solutions implement the same logic using 2 different methods:因此,总而言之,您不应使用 QGraphicsScene 而是使用 QGraphicsView,以下解决方案使用 2 种不同的方法实现相同的逻辑:

1. Creating a custom class of 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. Using eventfilter: 2. 使用事件过滤器:

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_())

On the other hand mapToGlobal() is a method that must be called by an instance, when you use QtWidgets.QWidget.mapToGlobal() there is no instance, my question is, what widget do you have the position?另一方面mapToGlobal()是一个必须由实例调用的方法,当你使用QtWidgets.QWidget.mapToGlobal()时没有实例,我的问题是,你有什么小部件? the position you have with respect to self, so you must use self.mapToGlobal() , that works for the objects belonging to a class that inherit from QWidget as QGraphicsView , but not in QGraphicsScene since it does not inherit from QWidget , it is not a widget as indicated in the lines above.您相对于 self 的位置,因此您必须使用self.mapToGlobal() ,它适用于属于从QWidget作为QGraphicsView继承的类的对象,但不适用于QGraphicsScene因为它不是从QWidget继承的,它不是上面几行中指示的小部件。

I have recently found a more universal way of getting the cursor position, if you don't want to go through sub classing and events.如果您不想通过子类和事件,我最近发现了一种更通用的获取光标位置的方法。

# get cursor position
cursor_position = QtGui.QCursor.pos()

print cursor_position
### Returns PySide2.QtCore.QPoint(3289, 296)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM