QMainWindow:showMaximized 仅在第一次调用时有效
QMainWindow:showMaximized only works the first time it is called
我有一个函数 button_max_slot
使用 showMaximized
最大化 window,另一个函数 button_restore_slot
恢复 window 的大小和地方。我第一次调用 button_max_slot
时效果很好,然后我使用 button_restore_function
来恢复 window 的大小和位置。但是我第二次调用 button_max_slot
来最大化 window,它没有用。我调用 self.isMaximized()
并且它 returns 是真的,但实际上 window 不 maximized.What 我应该如何解决这个问题?这是一个最小的可重现示例:
from PyQt5 import QtWidgets
import sys
class MyWindow(QtWidgets.QMainWindow):
last_geometry = None
def __init__(self):
super().__init__()
self.resize(960, 540)
self.ButtonMax = QtWidgets.QPushButton(self)
self.ButtonMax.setObjectName("ButtonMax")
self.ButtonMax.setText("Max")
self.ButtonMax.move(100, 100)
self.ButtonRestore = QtWidgets.QPushButton(self)
self.ButtonRestore.setText("Restore")
self.ButtonRestore.setObjectName("ButtonRestore")
self.ButtonRestore.move(300, 100)
self.ButtonRestore.setEnabled(False)
self.ButtonMax.clicked.connect(self.button_max_slot)
self.ButtonRestore.clicked.connect(self.button_restore_slot)
def button_max_slot(self):
self.last_geometry = self.geometry()
self.showMaximized()
self.ButtonRestore.setEnabled(True)
self.ButtonMax.setEnabled(False)
def button_restore_slot(self):
self.setGeometry(self.last_geometry)
self.ButtonRestore.setEnabled(False)
self.ButtonMax.setEnabled(True)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myshow = MyWindow()
myshow.show()
sys.exit(app.exec_())
tl;博士
使用 showNormal()
而不是 setGeometry()
来恢复 window 状态。
说明
虽然不直观,但仍然可以设置 window 的几何形状,即使它的状态 应该 不 允许它,那是因为设置 window 的状态与设置其几何形状 不同 。
简单地说,设置window状态告诉底层platform/window管理器根据指定状态“选择”window的几何结构,而设置几何结构要求系统显式设置 window 的位置和大小。系统是否允许,另当别论。
需要考虑的一件重要事情是 QWidget(即使是顶级的,包括 QDialog 或 QMainWindow)不是显示在屏幕上的实际 window屏幕。您看到的是 QWindow(该小部件的系统 window 的抽象表示),它实际上 包含 QWidget(或其任何继承的类)。设置状态作用于 QWindow,而设置几何通常作用于包含的小部件,不包括可能的 window 框架。
例如,我能够在我的 Linux 系统上重现您的问题,但是 ekhumoro cannot,即使我们都使用 Linux(我们都使用 相似 window 经理,但他们仍然不同:他在 OpenBox,我在 FluxBox)。此外,即使使用系统功能,我在按下“最大”按钮后也会出现不一致的行为。
事实上 you got 最大化的 window 状态,即使它不像 看起来 那样,与此完全相关:state 最大化,几何不是(因为你改变了它)。
反过来考虑:您可以手动调整 window 的大小,以便 精确地 占据整个可用屏幕大小,但这并不能做到maximized:您可能仍然可以在其标题栏中看到“最大化”按钮(不是“标准化”按钮),甚至可能看到通常隐藏的 window 边框window 实际上 已最大化。
请注意,在不同的 OS 或 window 管理器上显示的不一致行为依赖于两个方面:OS/wm 实现和 Qt 尝试在所有系统中使用“标准化”行为.
解决方案很简单:只需使用 showNormal()
而不是 setGeometry()
来恢复状态。
它通常适用于所有系统,但 linux 上一些非常具体的 window 管理器除外(可能在最近的 Windows/MacOS 版本中有一些“非标准”行为),但这是接受的方法。
对于这些情况,您可以考虑通过覆盖该事件的顶层 window 的 changeEvent()
, checking if the event.type()
is a WindowStateChange
and eventually decide the behavior based on the current windowState()
and the oldState()
来存储和恢复 几何。
请记住,window 状态是 标志 ,因此它们可以是 Qt.WindowState
枚举的 OR
组合。
我有一个函数 button_max_slot
使用 showMaximized
最大化 window,另一个函数 button_restore_slot
恢复 window 的大小和地方。我第一次调用 button_max_slot
时效果很好,然后我使用 button_restore_function
来恢复 window 的大小和位置。但是我第二次调用 button_max_slot
来最大化 window,它没有用。我调用 self.isMaximized()
并且它 returns 是真的,但实际上 window 不 maximized.What 我应该如何解决这个问题?这是一个最小的可重现示例:
from PyQt5 import QtWidgets
import sys
class MyWindow(QtWidgets.QMainWindow):
last_geometry = None
def __init__(self):
super().__init__()
self.resize(960, 540)
self.ButtonMax = QtWidgets.QPushButton(self)
self.ButtonMax.setObjectName("ButtonMax")
self.ButtonMax.setText("Max")
self.ButtonMax.move(100, 100)
self.ButtonRestore = QtWidgets.QPushButton(self)
self.ButtonRestore.setText("Restore")
self.ButtonRestore.setObjectName("ButtonRestore")
self.ButtonRestore.move(300, 100)
self.ButtonRestore.setEnabled(False)
self.ButtonMax.clicked.connect(self.button_max_slot)
self.ButtonRestore.clicked.connect(self.button_restore_slot)
def button_max_slot(self):
self.last_geometry = self.geometry()
self.showMaximized()
self.ButtonRestore.setEnabled(True)
self.ButtonMax.setEnabled(False)
def button_restore_slot(self):
self.setGeometry(self.last_geometry)
self.ButtonRestore.setEnabled(False)
self.ButtonMax.setEnabled(True)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myshow = MyWindow()
myshow.show()
sys.exit(app.exec_())
tl;博士
使用 showNormal()
而不是 setGeometry()
来恢复 window 状态。
说明
虽然不直观,但仍然可以设置 window 的几何形状,即使它的状态 应该 不 允许它,那是因为设置 window 的状态与设置其几何形状 不同 。
简单地说,设置window状态告诉底层platform/window管理器根据指定状态“选择”window的几何结构,而设置几何结构要求系统显式设置 window 的位置和大小。系统是否允许,另当别论。
需要考虑的一件重要事情是 QWidget(即使是顶级的,包括 QDialog 或 QMainWindow)不是显示在屏幕上的实际 window屏幕。您看到的是 QWindow(该小部件的系统 window 的抽象表示),它实际上 包含 QWidget(或其任何继承的类)。设置状态作用于 QWindow,而设置几何通常作用于包含的小部件,不包括可能的 window 框架。
例如,我能够在我的 Linux 系统上重现您的问题,但是 ekhumoro cannot,即使我们都使用 Linux(我们都使用 相似 window 经理,但他们仍然不同:他在 OpenBox,我在 FluxBox)。此外,即使使用系统功能,我在按下“最大”按钮后也会出现不一致的行为。
事实上 you got 最大化的 window 状态,即使它不像 看起来 那样,与此完全相关:state 最大化,几何不是(因为你改变了它)。
反过来考虑:您可以手动调整 window 的大小,以便 精确地 占据整个可用屏幕大小,但这并不能做到maximized:您可能仍然可以在其标题栏中看到“最大化”按钮(不是“标准化”按钮),甚至可能看到通常隐藏的 window 边框window 实际上 已最大化。
请注意,在不同的 OS 或 window 管理器上显示的不一致行为依赖于两个方面:OS/wm 实现和 Qt 尝试在所有系统中使用“标准化”行为.
解决方案很简单:只需使用 showNormal()
而不是 setGeometry()
来恢复状态。
它通常适用于所有系统,但 linux 上一些非常具体的 window 管理器除外(可能在最近的 Windows/MacOS 版本中有一些“非标准”行为),但这是接受的方法。
对于这些情况,您可以考虑通过覆盖该事件的顶层 window 的 changeEvent()
, checking if the event.type()
is a WindowStateChange
and eventually decide the behavior based on the current windowState()
and the oldState()
来存储和恢复 几何。
请记住,window 状态是 标志 ,因此它们可以是 Qt.WindowState
枚举的 OR
组合。