Pyside2, как получить положение мыши? - PullRequest
0 голосов
/ 20 сентября 2018

Я хочу получить положение мыши в моем приложении 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_()

Мне очень интересно, как я могу получить свою мышку поз ...

1 Ответ

0 голосов
/ 20 сентября 2018

Насколько я понимаю, вы хотите получить позицию в окне, если щелкнуть где-нибудь в виджете.

Чтобы решить эту проблему, логика выглядит следующим образом:

  • Получить положение мыши относительно виджета
  • Преобразовать эту позицию в глобальную позицию, то есть относительно экрана.
  • Преобразовать эту глобальную позицию в позицию относительно окна.

Для первого шага, если используется 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Следующие решения реализуют одну и ту же логику, используя 2 разных метода:

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.mapToGlobal(), который работает для объектов, принадлежащих к классу, которые наследуются от QWidget как QGraphicsView, но не от QGraphicsScene, так как он не наследуется от QWidget, это не виджет, как указано в строках выше.

...