Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pyside2如何获取鼠标位置?_Python_Python 3.x_Qgraphicsview_Qgraphicsscene_Pyside2 - Fatal编程技术网

Python Pyside2如何获取鼠标位置?

Python Pyside2如何获取鼠标位置?,python,python-3.x,qgraphicsview,qgraphicsscene,pyside2,Python,Python 3.x,Qgraphicsview,Qgraphicsscene,Pyside2,我想在pyside2应用程序中获得鼠标位置(不是QCursor提供的桌面鼠标位置),我尝试了两种方法。下面是我的密码 import sys from PySide2 import QtGui, QtWidgets, QtCore class Palette(QtWidgets.QGraphicsScene): def __init__(self, parent=None): super().__init__(parent) def mousePressEv

我想在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_()

我很想知道如何获得我的鼠标位置。

据我所知,如果您单击小部件中的任何位置,您希望获得窗口上的位置

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

  • 获取鼠标相对于小部件的位置
  • 将该位置转换为全局位置,即相对于屏幕的位置
  • 将该全局位置转换为相对于窗口的位置
对于第一步,如果使用了
mousePressEvent()
event.pos()
返回相对于小部件的位置

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

对于第三步,使用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)

更新:

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_())
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_())
qgraphicscene
不是小部件,也不是可视元素,尽管它是可视元素表示的一部分:
QGraphicsView
。为了让你们理解,我将用一个类比来解释你们,假设有一个摄影师记录了一个场景,在这个例子中,
qgraphicscene
就是场景,
QGraphicsView
就是摄像机记录的,也就是说,它显示了一段
qgraphicscene
,所以可能有另一个摄影师从另一个点记录场景,所以它会从另一个角度显示相同的场景,所以场景的位置取决于摄像机,所以如果你现在的问题相当于说点P相对于摄像机i-th的位置是什么,那么从场景看是不可能的,你应该从照相机里拿出来

总之,您不应该使用QGraphicscene,而应该使用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_())
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_())
2。使用eventfilter:

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_())
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()
是一个必须由实例调用的方法,当您使用
qtwidts.QWidget.mapToGlobal()
没有实例时,我的问题是,您的位置是什么?您相对于self的位置,因此必须使用
self.mapToGlobal()
,它适用于属于类的对象,该类作为
QGraphicsView
QWidget
继承,但不在
qgraphicscene
中,因为它不从
QWidget
继承,它不是上面几行所示的小部件。

如果您不想经历子分类和事件,我最近发现了一种更通用的获取光标位置的方法

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

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

非常感谢。正如你所说,我误解了场景和景色之间的关系。我试图在鼠标位置画一个矩形。谢谢你的解决方案,我解决了这个问题!谢谢你的热情回应!