如何在最大化还原QMainWindow后保留用户调整的QDockWidget宽度
解决QMainWindow中QDockWidget最大化还原后宽度重置的问题
问题核心是QMainWindow在窗口状态切换(最大化/还原)时,会默认重置两侧停靠控件的宽度分配。要保留用户自定义的宽度,需要手动记录并恢复dock的尺寸。
修改后的代码
# -*- coding: utf-8 -*- import sys from PyQt5.QtCore import Qt, QEvent from PyQt5.QtWidgets import QMainWindow, QApplication, QDockWidget, QWidget class WindowMain(QMainWindow): def __init__(self): super().__init__() self.setWindowFlags(Qt.WindowType.WindowMinimizeButtonHint | Qt.WindowType.WindowMaximizeButtonHint | Qt.WindowType.WindowCloseButtonHint) self.resize(800, 600) self.setWindowTitle('Symptoms') # 保存用户调整的dock宽度和窗口正常状态尺寸 self._normal_window_size = self.size() self._dock1_width = 0 self.dock1 = QDockWidget('DockWidget1', self) self.dock2 = QDockWidget('DockWidget2', self) self.dock1.setWidget(QWidget()) self.dock1.widget().setStyleSheet('background: #FFC0C0') self.dock2.setWidget(QWidget()) self.dock2.widget().setStyleSheet('background: #C0FFC0') self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, self.dock1) self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dock2) # 监听窗口状态变化 self.windowStateChanged.connect(self._on_window_state_changed) # 监听dock尺寸变化,更新记录的宽度 self.dock1.widget().installEventFilter(self) def eventFilter(self, obj, event): # 捕捉dock内部控件的尺寸变化事件,更新dock1的宽度记录 if obj == self.dock1.widget() and event.type() == QEvent.Resize: self._dock1_width = obj.width() return super().eventFilter(obj, event) def _on_window_state_changed(self, old_state, new_state): if old_state == Qt.WindowNoState and new_state == Qt.WindowMaximized: # 窗口即将最大化,记录当前dock1宽度和窗口正常尺寸 self._normal_window_size = self.size() if self._dock1_width == 0: # 初始状态下dock1的宽度 self._dock1_width = self.dock1.widget().width() elif old_state == Qt.WindowMaximized and new_state == Qt.WindowNoState: # 窗口从最大化还原,恢复dock1的宽度 self.resize(self._normal_window_size) # 设置dock1的宽度,通过调整主窗口中心区域的宽度间接实现 central_width = self._normal_window_size.width() - self._dock1_width - self.dock2.widget().width() self.setCentralWidget(QWidget()) self.centralWidget().setFixedWidth(central_width) def main(): app = QApplication(sys.argv) wndMain = WindowMain() wndMain.show() app.exec_() if __name__ == '__main__': main()
关键实现说明
- 尺寸记录:通过
eventFilter监听左侧dock内部控件的Resize事件,实时保存用户调整的宽度;在窗口即将最大化时,记录当前窗口的正常尺寸和dock宽度。 - 状态恢复:当窗口从最大化还原时,先恢复窗口的正常尺寸,再通过设置主窗口中心区域的固定宽度,间接恢复左右dock的宽度分配。这种方式不需要设置dock的固定宽高,完全保留用户的自定义调整权限。
内容的提问来源于stack exchange,提问作者Dawn Wren
相关产品推荐
相关产品推荐

