PyQt窗口异常:非全屏状态却显示全屏的原因与解决
问题背景
我用Qt Designer创建小型GUI并转成Python代码后,期望窗口以(1852,1136)的窗口模式启动,但它自动显示为铺满屏幕的状态。
排查过程
- 尝试设置窗口状态为
Qt.WindowNoState,无效果;但设置Qt.WindowMinimized有效,排除代码逻辑问题。 - 调用
w.resize(1852, 1136)后,窗口尺寸仍无变化,但调整为(1200,1136)这类小尺寸时生效。 - 测试发现临界值:设置为
(1536,1136)时窗口正常显示,设为(1537,1136)就会铺满屏幕,但isFullScreen()返回False。
测试代码输出
# 打印初始尺寸 print(w.size()) >> PyQt5.QtCore.QSize(1852, 1136) # 检查是否全屏 print(w.isFullScreen()) >> False # 切换至全屏 w.showFullScreen() # 打印全屏后尺寸 print(w.size()) >> PyQt5.QtCore.QSize(1852, 1136) # 检查是否全屏 print(w.isFullScreen()) >> True # 切换至普通窗口模式 w.showNormal() # 打印普通模式后尺寸 print(w.size()) >> PyQt5.QtCore.QSize(1852, 1136) # 检查是否全屏 print(w.isFullScreen()) >> False # 调整尺寸至1537 w.resize(1537, 1136) # 打印调整后尺寸 print(w.size()) >> PyQt5.QtCore.QSize(1537, 1136) # 调整尺寸至1536 w.resize(1536, 1136) # 打印调整后尺寸 print(w.size()) >> PyQt5.QtCore.QSize(1536, 1136)
疑问
- 为何未设置全屏,窗口却以铺满屏幕的状态启动?
- 如何修复该问题?
运行环境:Ubuntu 20.04 LTS,4K显示屏,(1852,1136)尺寸完全适配;点击窗口右上角“窗口模式”按钮可将窗口缩小至指定尺寸。
最小复现代码
from PyQt5 import QtCore, QtGui, QtWidgets import sys class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1852, 1136) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1852, 22)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) app = QtWidgets.QApplication(sys.argv) ex = Ui_MainWindow() w = QtWidgets.QMainWindow() ex.setupUi(w) w.show() # 尺寸为(1852, 1136)时显示全屏 print(f"App is in fullscreen even though it's set at {w.size()} and Fullscreen check returns: {w.isFullScreen()}") # 调整尺寸至(1536, 1136) w.resize(1536, 1136) print(f"App is not in Fullscreen anymore after resize: {w.size()}") sys.exit(app.exec_())
代码输出
App is in fullscreen even though it's set at PyQt5.QtCore.QSize(1852, 1136) and Fullscreen check returns: False
App is not in Fullscreen anymore after resize: PyQt5.QtCore.QSize(1536, 1136)
解答
问题原因
这是Ubuntu GNOME桌面环境的窗口管理行为导致的:当窗口尺寸接近屏幕可用区域(减去顶部状态栏、侧边栏等系统UI)时,窗口管理器会自动将窗口最大化(注意不是全屏,全屏会隐藏所有系统UI)。而Qt的isFullScreen()仅检测是否进入真正的全屏模式(隐藏标题栏、状态栏等),所以返回False。
临界值1536应该是你的屏幕可用宽度减去窗口装饰(标题栏、边框)后的阈值,当窗口宽度超过这个值,窗口管理器就触发了自动最大化。
修复方案
可以通过以下几种方法禁用窗口的自动最大化特性:
方法1:设置固定尺寸标志
在窗口显示前添加代码,告诉窗口管理器窗口尺寸固定,禁止自动调整或最大化:
w.setWindowFlags(w.windowFlags() | QtCore.Qt.MSWindowsFixedSizeDialogHint)
方法2:禁用最大化按钮并手动定位窗口
如果需要保留窗口可调整大小的能力,仅禁止自动最大化:
# 禁用最大化按钮 w.setWindowFlags(w.windowFlags() & ~QtCore.Qt.WindowMaximizeButtonHint) # 将窗口居中显示 screen_geo = QtWidgets.QApplication.desktop().availableGeometry() x = (screen_geo.width() - 1852) // 2 y = (screen_geo.height() - 1136) // 2 w.move(x, y)
方法3:延迟调整尺寸
窗口管理器可能在窗口显示后覆盖尺寸设置,可延迟一段时间再强制调整:
# 窗口显示后100毫秒强制设置尺寸 QtCore.QTimer.singleShot(100, lambda: w.resize(1852, 1136))
将这段代码放在w.show()之后即可。
内容的提问来源于stack exchange,提问作者Amo

