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

切换QMainWindow中心部件时如何防止QDockWidget异常放大?

Qt QDockWidget切换Central Widget后尺寸异常问题

我有一个包含QDockWidget和Central Widget的QMainWindow,Central Widget可根据用户选择切换,QDockWidget始终保留。未调整QDockWidget尺寸时,切换Central Widget不会影响其尺寸(保持size hint);但用户手动调整过QDockWidget尺寸后,切换Central Widget时它会异常放大并挤占Central Widget的空间。

问题演示

Qt Dock Widget尺寸异常

复现代码(Qt5.15)

#include <QApplication>
#include <QLayout>
#include <QLabel>
#include <QMainWindow>
#include <QDockWidget>
#include <QToolBar>
#include <QTimer>

class Widget : public QWidget
{
public:
    Widget(const QString& aName, QSize aSize, QWidget * parent = nullptr)
        : QWidget(parent), size(aSize)
    {
        static int COUNT = 0;
        static QStringList COLORS = { "LightBlue", "LightGreen", "LightSalmon" };

        auto label = new QLabel(tr("%1 (%2x%3)").arg(aName).arg(size.width()).arg(size.height()), this);
        label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        label->setAlignment(Qt::AlignCenter);
        label->setWordWrap(true);
        label->setStyleSheet(QString("QLabel { background-color: %1 }").arg(COLORS.value(COUNT++ % COLORS.size())));

        auto mainLayout = new QVBoxLayout(this);
        mainLayout->addWidget(label);
    }

    QSize sizeHint() const override
    {
        return size;
    }

private:
    QSize size;
};

class MainWindow : public QMainWindow
{

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
    {
        // 创建工具栏
        addToolBar("Tool bar")->addAction("Switch central Widget", this, &MainWindow::switchCentralWidget);

        // 创建初始Central Widget
        switchCentralWidget();

        // 创建Dock Widget
        auto dockWidget = new QDockWidget("My dock widget");
        dockWidget->setWidget(new Widget("DOCK WIDGET", {200, 400}, this));
        addDockWidget(Qt::RightDockWidgetArea, dockWidget);
    }

private slots:

    void switchCentralWidget()
    {
        setCentralWidget(new Widget("CENTRAL WIDGET", {300, 400}, this));
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

尝试的临时方案

我尝试修改Central Widget和QDockWidget的尺寸策略但未成功,仅找到一种临时设置最大宽度的方法来阻止放大:

void switchCentralWidget()
{
    // 临时 hack
    for (auto dock : findChildren<QDockWidget *>()) {
        int width = dock->widget()->width();
        int maxWidth = dock->widget()->maximumWidth();
        dock->setMaximumWidth(width);
        QTimer::singleShot(1000, dock, [=] { dock->setMaximumWidth(maxWidth); });
    }

    setCentralWidget(new Widget("CENTRAL WIDGET", {300, 400}, this));
}

但这是不规范的临时方案,当QDockWidget的size hint被修改时(比如用户切换Central部件并修改Dock部件字体大小的场景)会出现问题。

需求

希望切换Central Widget时,QDockWidget能保持切换前的尺寸。


内容的提问来源于stack exchange,提问作者Niark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:12:09