我正在将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不同呢?
答案 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