Насколько я понимаю, вы хотите получить позицию в окне, если щелкнуть где-нибудь в виджете.
Чтобы решить эту проблему, логика выглядит следующим образом:
- Получить положение мыши относительно виджета
- Преобразовать эту позицию в глобальную позицию, то есть относительно экрана.
- Преобразовать эту глобальную позицию в позицию относительно окна.
Для первого шага, если используется 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
, это не виджет, как указано в строках выше.