PyQt5端口:如何隐藏窗口并让它出现在同一位置

时间:2016-10-16 19:40:11

标签: python pyqt4 porting pyqt5

我正在将PyQt4程序移植到PyQt5。其中一部分是隐藏窗口,截取窗口后面的区域并再次显示窗口,这对于PyQt4来说效果很好。

使用我的PyQt5端口,一切正常,但窗口出现在程序启动时的位置,而不是在调用hide()方法之前的位置。

我正在Linux机器上测试它。相关代码剥离为:

import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget,
                             QGridLayout, QPushButton)

class demo(QMainWindow):

    def __init__(self):
        super().__init__()

        mainWidget = QWidget(self)
        layout = QGridLayout(mainWidget)
        self.setCentralWidget(mainWidget)

        self.testButton = QPushButton(self)
        self.testButton.setText('Test')
        self.testButton.clicked.connect(self.hideMe)
        layout.addWidget(self.testButton, 0, 0)

    def hideMe(self):
        self.hide()
        QTimer.singleShot(300, self.showMe)

    def showMe(self):
        self.show()
        self.move(self.pos())

app = QApplication(sys.argv)
mainWindow = demo()
mainWindow.show()
sys.exit(app.exec_())

在showMe()中,self.pos()实际上包含正确的坐标,但窗口不会移动到那里(但是在启动后它就是它的“原始”位置。)

当我。 G。做一个self.move(10,10),窗口实际上是移动到那里。但是,只要我使用变量(我也试图将self.pos的x和y保存在变量中并使用它),窗口就会显示在启动后的位置。

为什么用整数调用move()实际上会移动窗口,但是带变量的move()调用不会?如何将窗口移动到隐藏之前的位置?

感谢您的帮助!

编辑(也许是为了找出区别):

使用PyQt4的代码完全相同:

import sys

from PyQt4.QtCore import QTimer
from PyQt4.QtGui import (QApplication, QMainWindow, QWidget,
                         QGridLayout, QPushButton)

class demo(QMainWindow):

    def __init__(self):
        super().__init__()

        mainWidget = QWidget(self)
        layout = QGridLayout(mainWidget)
        self.setCentralWidget(mainWidget)

        self.testButton = QPushButton(self)
        self.testButton.setText('Test')
        self.testButton.clicked.connect(self.hideMe)
        layout.addWidget(self.testButton, 0, 0)

    def hideMe(self):
        self.hide()
        QTimer.singleShot(300, self.showMe)

    def showMe(self):
        self.show()
        self.move(self.pos())

app = QApplication(sys.argv)
mainWindow = demo()
mainWindow.show()
sys.exit(app.exec_())

那么为什么Qt5会在这种情况下与Qt4不同呢?

3 个答案:

答案 0 :(得分:2)

似乎在Qt5中几何体不会被重新设置,如果它完全相同 - 但我不知道为什么这种行为发生了变化,或者它是否是一个bug。请注意,不仅仅是受影响的位置 - 也会忽略调整大小。

这是一个解决问题的黑客:

from PyQt5.QtCore import QMargins

class demo(QMainWindow):
    ...

    def hideMe(self):
        print('hide:', self.geometry())
        self.hide()
        QTimer.singleShot(300, self.showMe)

    def showMe(self):
        print('show1:', self.geometry())
        hack = QMargins(0, 0, 0, 1)
        self.setGeometry(self.geometry() + hack)
        self.show()
        self.setGeometry(self.geometry() - hack)
        print('show2:', self.geometry())

<强>更新

经过一番进一步调查后,似乎有一个更简单的解决方案。如果在首次显示窗口之前显式设置窗口的几何体,则在后续的hide()/ show()之后它不会移回其原始位置。在这种情况下,不需要其他黑客/解决方法。

答案 1 :(得分:1)

这确实看起来像个错误。

其他解决方法可能是设置QWindow位置而不是小部件位置,例如:

windowHandle()->setPosition(windowHandle()->position());

或在show()之前设置WA_Moved属性:

setAttribute(Qt::WA_Moved);

我认为ekhumoro的答案是最好的。如果你打算更好地使用变通方法,而不是隐含的黑客攻击。

答案 2 :(得分:0)

如果我在git config user.name git config user.email self.old_pos中使用hideMe,那么它适用于我(Linux)。

showMe