You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在最大化还原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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:27:25