6

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?

artomason
  • 3,625
  • 5
  • 20
  • 43

3 Answers3

5

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Spent hours researching that and couldn't figure it out. Thank you for the clear explanations. – artomason Nov 10 '18 at 06:20
  • @eyllanesc Is it a problem to have a return for the finction moveEvent? In my case when i add a 'return True' rises an error as 'TypeError: invalid result from MyClass.moveEvent()' – Rohithsai Sai Dec 19 '19 at 16:12
5

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

S. Nick
  • 12,879
  • 8
  • 25
  • 33
  • For me, this example always returns a main window position of x=-3, y=-30 irrespective of where I move the window. I am on Ubuntu 22.04. – Johnos Jan 13 '23 at 14:22
0

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)