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

如何让QDockWidget的子部件铺满整个停靠部件并随其 resize?

问题:QDockWidget内子部件无法随停靠部件resize铺满区域

我创建了一个带有QDockWidget的主窗口,停靠部件内包含自定义子部件MyWidget,希望子部件始终铺满停靠部件的区域,即使停靠部件发生resize。已将子部件的sizePolicy设置为Expanding,但该设置无效。

现象说明

  • 应用启动时:停靠部件尺寸小于主窗口,子部件能铺满停靠部件的客户区
    启动时状态
  • 拖动重新停靠后:子部件未随停靠部件resize,无法铺满区域
    重新停靠后状态

实际应用中,子部件内部包含带有多个组件的布局,需要所有组件都能拉伸缩放以填满父停靠部件的整个客户区。

最小示例代码

#include <QApplication>

#include <QMainWindow>
#include <QScopedPointer>
#include <iostream>
#include <QDockWidget>

struct MyWidget : public QWidget {
    MyWidget(QWidget * parent = nullptr);
    QSize sizeHint() const override;
    QSize minimumSizeHint() const override;
};

struct MainWindow : public QMainWindow {
    MainWindow(QWidget *parent = 0);

protected:
    void paintEvent(QPaintEvent *) override;
private:
    QScopedPointer<MainWindow> ui;
    QDockWidget * dock;
    MyWidget * wid;
};

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    dock = new QDockWidget(this);
    dock->setStyleSheet("border: 1px solid blue");
    wid = new MyWidget(dock);
    wid->setStyleSheet("border: 1px solid red");
    wid->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

void MainWindow::paintEvent(QPaintEvent * e)
{
    QMainWindow::paintEvent(e);
    std::cout << "Dock's  size " << dock->width() << ',' << dock->height() << '\n';
    std::cout << "child's size " << wid->width() << ',' << wid->height() << '\n';
    std::cout << "child's sizehint    " << wid->sizeHint().width() << ',' << wid->sizeHint().height() << '\n';
    std::cout << "child's minsizehint " << wid->minimumSizeHint().width() << ',' << wid->minimumSizeHint().height() << '\n';
}

MyWidget::MyWidget(QWidget * parent)
    : QWidget(parent)
{
}

QSize MyWidget::minimumSizeHint() const
{
    return QSize(153,154);
}

QSize MyWidget::sizeHint() const
{
    return QSize(150,151);
}

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

解决方案

核心问题是未正确将子部件设置为QDockWidget的内容部件,且未将停靠部件添加到主窗口的停靠区域。QDockWidget需要通过setWidget()方法指定内部主部件,而非直接将子部件设为它的子控件;同时必须调用addDockWidget()将停靠部件关联到主窗口的停靠区域,否则尺寸管理会异常。

修改步骤

  1. 正确关联QDockWidget与子部件:使用dock->setWidget(wid)替代直接将wid作为dock的子控件;
  2. 将停靠部件添加到主窗口:调用addDockWidget()指定停靠位置;
  3. 子部件内部布局(若有子组件):给MyWidget添加布局,确保内部组件能铺满自身区域。

修改后的关键代码

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    dock = new QDockWidget(this);
    dock->setStyleSheet("border: 1px solid blue");
    wid = new MyWidget(); // 无需指定父对象,setWidget会自动处理
    wid->setStyleSheet("border: 1px solid red");
    wid->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    // 关键:设置停靠部件的内容部件
    dock->setWidget(wid);
    // 将停靠部件添加到主窗口的左侧停靠区域
    addDockWidget(Qt::LeftDockWidgetArea, dock);
}

// 若MyWidget内部有子组件,添加布局示例
MyWidget::MyWidget(QWidget * parent)
    : QWidget(parent)
{
    QVBoxLayout* layout = new QVBoxLayout(this);
    // 示例:添加子控件到布局中
    // QPushButton* testBtn = new QPushButton("Test", this);
    // layout->addWidget(testBtn);
}

修改后,子部件会随QDockWidget的resize自动铺满整个区域,内部布局的组件也会同步拉伸适配。

内容的提问来源于stack exchange,提问作者lmat - Reinstate Monica

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:54:58