How to get the screen position of `QMainWindow` and print it?

Question:

I’m trying to get the screen position of QMainWindow and print the position (x,y) values. I have tried both self.pos() and self.mapToGlobal(self.pos()) and both of these return 0.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow


class MainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(400, 200)

        # PRINTS 0 0
        print(self.pos().x(), self.pos().y())

        # PRINTS 0 0
        print(self.mapToGlobal(self.pos()).x(), self.mapToGlobal(self.pos()).y())


app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

I’m using Python 3.7 and PyQt 5.11, how can I achieve this?

Asked By: artomason

||

Answers:

The position of a widget is with respect to the parent if it has it, and if it does not have it is with respect to the screen, so in the case of MainWindow, since it is a window, pos() should be used, if it were a widget that has a parent you must use self.mapToGlobal(QtCore.QPoint(0, 0)) since it is the top-left position.

On the other hand the initial position of every widget is QPoint(0, 0), and if it is a window the OS manipulates its position and moves it, so you get the value of (0, 0), so in your case you must track the change of position, for example using moveEvent:

import sys
from PyQt5 import QtCore, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(400, 200)

    def moveEvent(self, e):
        print(self.pos())
        super(MainWindow, self).moveEvent(e)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
Answered By: eyllanesc

I’ll add the link http://doc.qt.io/qt-5/application-windows.html#window-geometry and an example:

import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, 
                             QVBoxLayout, QTextEdit, QPushButton)


class MainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(400, 200)


        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)

        self.textEdit = QTextEdit()
        self.btn = QPushButton("get the screen position of `QMainWindow`")
        self.btn.clicked.connect(self.btnClicked)

        layoutV = QVBoxLayout(centralWidget)
        layoutV.addWidget(self.textEdit)
        layoutV.addWidget(self.btn)

        self.textEdit.append("Start:")
        self.textEdit.append("pos.x=`{}`, pos.y=`{}`"
                             "".format(self.pos().x(), self.pos().y()))
        self.textEdit.append("geometry.x=`{}`, geometry.y=`{}`"
                             "".format(self.geometry().x(), self.geometry().y()))
        self.textEdit.append("--------------------------------------")

    def btnClicked(self):
        self.textEdit.append("pos.x=`{}`, pos.y=`{}`"
                             "".format(self.pos().x(), self.pos().y()))
        self.textEdit.append("geometry.x=`{}`, geometry.y=`{}`"
                             "".format(self.geometry().x(), self.geometry().y()))



    def moveEvent(self, event):    # QMoveEvent      
        print("x=`{}`, y=`{}`".format(event.pos().x(), event.pos().y()))
        super(MainWindow, self).moveEvent(event)

    def resizeEvent(self, event):  # QResizeEvent      
        print("w=`{}`, h=`{}`".format(event.size().width(), event.size().height())) 
        super(MainWindow, self).resizeEvent(event)        


app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

enter image description here

Answered By: S. Nick

I thought I’d chime in as I’ve been working on the same thing. Storing and restoring the window position between sessions. Here’s what worked for me with python 2.717 and Qute 1.3.2

from Qt import QtWidgets
from Qt import QtCore

class MainUI(QtWidgets.QMainWindow):
    def __init__(self):
        self.installEventFilter(self)
        self._nLastEvent = None

    def resizeEvent(self, event):
        super(MainWindow, self).resizeEvent(event)
        s = self.size()
        print(s.width())
        print(s.height())

    def eventFilter(self, obj, event):
        if self._nLastEvent == QtCore.QEvent.Move and event.type() == QtCore.QEvent.WindowActivate:
            pos = self.pos()
            print(pos.x())
            print(pos.y())
        self._nLastEvent = event.type()
        return super(MainUI, self).eventFilter(obj, event)

Answered By: Brent Forrest