如何获取 `QMainWindow` 的屏幕位置并打印出来?

6

我试图获取 QMainWindow 的屏幕位置,并且 print 出这个位置的 (x,y) 值。我已经尝试了 self.pos()self.mapToGlobal(self.pos()) 两种方法,但两者都返回 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_())

我正在使用Python 3.7和PyQt 5.11,我该如何实现这个功能?
3个回答

5
小部件的位置是相对于其父级的,如果有父级,而如果没有,则相对于屏幕,因此在MainWindow的情况下,由于它是窗口,应该使用pos(),如果是具有父级的小部件,则必须使用self.mapToGlobal(QtCore.QPoint(0, 0)),因为它是左上角位置。
另一方面,每个小部件的初始位置都是QPoint(0, 0),如果它是一个窗口,操作系统会操纵其位置并移动它,因此您会得到值(0,0),因此在您的情况下,您必须跟踪位置的变化,例如使用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_())

花了好几个小时的时间研究,但还是无法理解。感谢您提供清晰易懂的解释。 - artomason
@eyllanesc 在函数moveEvent中添加'return True'会出现问题吗?在我的情况下,当我添加'return True'时,会出现错误'TypeError:invalid result from MyClass.moveEvent()'。 - Rohithsai Sai

5
我会添加链接 http://doc.qt.io/qt-5/application-windows.html#window-geometry 和一个例子:
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


对我来说,无论我将窗口移动到哪里,这个示例始终返回一个主窗口位置为x=-3,y=-30。我使用的是Ubuntu 22.04。 - Johnos

0

我想说一下,因为我一直在做同样的事情。在会话之间存储和恢复窗口位置。这是在 Python 2.717 和 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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接