sizeHint() minimumSizeHint() sizePolicy() 的使用

本文深入解析Qt中的sizeHint、minimumSizeHint属性及其与sizePolicy的相互作用,通过实例演示了每个属性的用法及应用场景。包括如何通过设置这些属性来控制QWidget的大小调整,以及它们之间的区别与联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


之前一直对这几个属性搞不清楚,前几天仔仔细细地看了文档解释并做了一些测试,现在来归纳一下:

首先我们得知道这几个属性保存的值是什么,它们分别是用来干什么的。

  • sizeHint
  • [From Qt Doc: This property holds the recommended size for the widget. If the value of this property is an invalid size, no size is recommended. The default implementation of sizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise. ] 这个属性所保存的 QSize 类型的值是一个被推荐给窗口或其它组件(为了方便下面统称为widget)的尺寸,也就是说一个 widget 该有多大,它的一个参考来源就是这个sizeHint 属性的值,而这个值由 sizeHint() 函数来确定。但是 widget 的大小的确定还有其它因素作用,下面会讲到。现在只需知道 sizeHint() 会返回一个被推荐的尺寸。那么这个尺寸的取值是怎样的呢?当它是一个无效值的时候(sizeHint().isValid() 返回 false,QSize 中 width 或者 height 有一个为复数就会是无效的),什么作用也没有;当它是一个有效值的时候,它就成了 widget 大小的一个参考。Qt 中对 sizeHint() 的默认实现是这样的:当 widget 没有布局(layout),返回无效值;否则返回其 layout 的首选尺寸(preferred size)。
       1: QWidget *widget = new QWidget;
       2: widget->show();
       3: qDebug() << widget->width() << "," << widget->height();
       4: qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();
       1: //output:
       2: //1009 , 520
       3: //-1 , –1
    输出结果中第二行:sizeHint() 返回的是一个无效的 QSize,因为 widget 没有布局。
       1: QWidget *widget = new QWidget;
       2: QHBoxLayout *layout = new QHBoxLayout;
       3: QPushButton *button = new QPushButton("Ggicci");
       4: layout->addWidget(button);
       5: widget->setLayout(layout);
       6: widget->show();
       7: qDebug() << widget->width() << "," << widget->height();
       8: qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();
       9: qDebug() << button->width() << "," << button->height();
    2012-10-26_1729
       1: //output:
       2: //112 , 45 
       3: //97 , 45 
       4: //90 , 23
    输出结果中第一行:widget 的实际尺寸 (112, 45);
    输出结果中第二行:sizeHint() 返回 layout 的首选尺寸(97,45)供 widget 参考;
    输出结果中第三行:中间 button 的实际大小;
    从输出结果中可以证明以上说过的两点:
    1) 在 widget 有 layout 的情况下,其 sizeHint() 函数返回的是有效值作为其自身实际尺寸的参考
    2) sizeHint() 返回的值并不一定会作为 widget 的实际尺寸,因为 widget 的尺寸的决定还有其它因素作用;

  • minimumSizeHint
  • [From Qt Doc: This property holds the recommended minimum size for the widget. If the value of this property is an invalid size, no minimum size is recommended. The default implementation of minimumSizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's minimum size otherwise. Most built-in widgets reimplement minimumSizeHint().] Qt 中的 widget 有 size 和 minimumSize 两个属性,比较好理解的是上面的sizeHint 是作为 size 的参考的,那么 minimumSizeHint 是作为 minimumSize 的参考的。minimumSizeHint() 的默认实现同 sizeHint() 基本一样:在 widget 无 layout 的情况下返回无效值;否则返回 layout 的最小尺寸(minimum size),注意与上面的首选尺寸不同哦!有同学会问 preferred size 和 minimum size 的区别:preferred size 由 layout 的 sizeHint() 函数返回,minimum size 由 layout 的 minimumSize() 函数返回;前者的实现会根据 layout 的种类的变化而变化,比如在 QHBoxLayout 和 QVBoxLayout 中各放置同样的两个 QPushButton,两者的 sizeHint() 返回的值是不一样的,后者是返回能够容纳下所有包含在 layout 内的组件的最小尺寸。Qt 中大多数内置的 widget 都已经重新实现了 minimumSizeHint()。你可以自己写自己的 widget 然后重新实现 sizeHint()、minimumSizeHint() 这些函数来达到自己的布局效果。
  • [From Qt Doc: QLayout will never resize a widget to a size smaller than the minimum size hint unless minimumSize() is set or the size policy is set to QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint will be ignored.] layout 永远也不会把一个 widget 的大小设置到比 minimumSizeHint() 返回的尺寸还小,除非 widget 设置了最小尺寸或者其 sizePolicy 属性设置了 QSizePolicy::Ignore。如果 widget 通过 setMinimumSize() 设置了最小尺寸,那么 minimumSizeHint 的作用就会被忽略掉。我们知道如果在一个 layout 里面添加一些子 widget,然后窗口应用这个 layout 的时候,一般情况下我们是无法缩放到使其中的子 widget 看不见的。如下:
       1: QWidget *widget = new QWidget;
       2: widget->setMinimumSize(10, 10);
       3: QVBoxLayout *layout = new QVBoxLayout;
       4: QPushButton *button = new QPushButton("Ggicci");
       5: layout->addWidget(button);
       6: widget->setLayout(layout);
       7: widget->show();
    这里同上显示一个含有 QPushButton 的 QWidget,不过在这里设置了其最小尺寸为(10, 10),此时 minimumSizeHint() 将不起作用,也就是我们可以把widget 缩放到(10, 10),不过这是理论上的哦,亲~(在这里你讲看到一个例外),以下就是缩小到了极致:(112,10),同学,是否在思考为什么 width 无法缩小到比 112 更小了。其实这是 widget 和 windows 系统的共同问题,第一 widget 默认有 min,max,close 三个按钮,也就是右上角的最小化、最大化、关闭按钮,这导致了 width 无法继续缩小。其实通过 widget->setWindowFlags(Qt::Window | Qt::WindowTitleHint); 可以把 min, max 按钮给去了,这样的 widget 的 width 就可以比之前更小一点啦,如下右图。
    2012-10-26_1819 2012-10-26_1837

  • sizePolicy
  • [From Qt Doc: This property holds the default layout behavior of the widget. If there is a QLayout that manages this widget's children, the size policy specified by that layout is used. If there is no such QLayout, the result of this function is used.] 这个属性保存了该 widget 的默认布局属性,如果它有一个 layout 来布局其子 widgets,那么这个 layout 的 size policy 将被使用;如果该 widget 没有 layout 来布局其子 widgets,那么它的 size policy 将被使用。默认的 policy 是 Preferred/Preferred。QSizePolicy::Policy 枚举值有如下几个:

Constants

Description

QSizePolicy::Fixedwidget 的实际尺寸只参考 sizeHint() 的返回值,不能伸展(grow)和收缩(shrink)
QSizePolicy::Minimum可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能缩小到的最小尺寸
QSizePolicy::Maximum可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能伸展到的最大尺寸
QSizePolicy::Preferred可以伸展和收缩,但没有优势去获取更大的额外空间使自己的尺寸比 sizeHint() 的返回值更大
QSizePolicy::Expanding可以伸展和收缩,它会尽可能多地去获取额外的空间,也就是比 Preferred 更具优势
QSizePolicy::MinimumExpanding可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能缩小到的最小尺寸,同时它比 Preferred 更具优势去获取额外空间
QSizePolicy::Ignored忽略 sizeHint() 的作用

Y8IDK

从上图中可以看出 Preferred 虽然可以收缩得比 sizeHint() 更小,但是最小由 minimumSizeHint() 限制

    • QSizePolicy::Fixed
       1: QWidget *widget = new QWidget;
       2: QHBoxLayout *layout = new QHBoxLayout;
       3: QPushButton *button = new QPushButton("Ggicci");
       4: //button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
       5: layout->addWidget(button);
       6: widget->setLayout(layout);
       7: widget->show();
    在第4行代码注释掉的情况下:QPushButton 默认的 sizePolicy 是垂直方向 Fixed,水平方向 Preferred,故水平方向会伸展2012-10-26_2030
    没有注释掉的情况下:
    2012-10-26_2035
    • QSizePolicy::Preferred 和 QSizePolicy::Expanding 的区别:两者都可以伸展和收缩,但是区别在于谁可以伸展地更牛B
       1: QWidget *widget = new QWidget;
       2: QHBoxLayout *layout = new QHBoxLayout;
       3: QPushButton *button1 = new QPushButton("Ggicci");
       4: QPushButton *button2 = new QPushButton("Mingjie Tang");
       5: button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
       6: button2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
       7: layout->addWidget(button1);
       8: layout->addWidget(button2);
       9: widget->setLayout(layout);
      10: widget->show();
    两者一样牛B(在水平方向上,垂直方向不构成额外空间竞争关系):
    2012-10-26_2042
       1: QWidget *widget = new QWidget;
       2: QHBoxLayout *layout = new QHBoxLayout;
       3: QPushButton *button1 = new QPushButton("Ggicci");
       4: QPushButton *button2 = new QPushButton("Mingjie Tang");
       5: button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
       6: button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
       7: layout->addWidget(button1);
       8: layout->addWidget(button2);
       9: widget->setLayout(layout);
      10: widget->show();
    button2更牛B(在水平方向上构成竞争关系):
    2012-10-26_2047
    • 有了上述的样例,QSizePolicy::Minimum, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored 就比较好理解了吧
<think>嗯,用户想了解Qt布局管理器的使用方法和原理。首先,我需要回忆一下Qt的布局管理器有哪些类型。根据引用[2],Qt提供了5种布局管理器,分别是QVBoxLayout、QHBoxLayout、QGridLayout、QFormLayout和QStackedLayout。这应该是基础知识,需要先介绍每种布局的作用。 然后,用户可能想知道如何使用这些布局。比如,如何在代码中创建和添加控件。可能需要举一个例子,比如垂直布局中添加按钮。记得提到addWidget和addLayout方法,这样用户可以知道如何嵌套布局。 接下来是工作原理部分。引用[3]提到布局管理器通过setGeometry来设置子部件的位置和大小。需要解释布局管理器在调整窗口大小时如何重新计算子部件的位置。同时,sizeHintminimumSizeHint这些概念也很重要,需要说明它们的作用。 另外,引用[4]提到了sizePolicy,也就是大小策略,这影响部件在布局中的拉伸行为。比如,QSizePolicy::Expanding会让部件尽可能扩展。这部分需要详细说明,因为用户可能遇到控件不按预期调整的情况。 用户可能还关心布局的嵌套使用,比如如何在水平布局中嵌入垂直布局,这样能创建复杂的界面。需要强调布局管理器自动处理子部件的排列和调整,开发者不需要手动计算坐标。 还有,布局管理器的继承关系,如QBoxLayout是QVBoxLayout和QHBoxLayout的父类,这可能对理解它们的共同点有帮助,但可能用户更关注具体用法,所以可能不需要深入讨论继承结构。 最后,常见问题比如如何设置边距和间距,如何让某个部件固定大小,或者如何实现自适应布局。这部分可以通过相关问题来引导用户进一步学习。例如,网格布局的对齐方式,或者如何处理动态添加控件后的布局更新。 需要确保回答结构清晰,分点说明使用方法和原理,结合代码示例和引用中的知识点。可能还需要检查每个引用内容,确保引用标识正确,比如引用[1]提到坐标系,这可能和布局管理器计算位置有关,但用户的问题更关注使用方法和原理,所以可能不需要特别强调坐标系,除非在解释布局计算时需要提到。 总之,回答应该先介绍布局类型,然后使用方法,接着工作原理,最后常见问题和相关扩展问题。保持语言简洁,用例子帮助理解,并正确引用参考资料。</think>### Qt布局管理器使用方法及原理介绍 #### 一、布局管理器类型 Qt提供5种标准布局管理器,对应以下类: 1. **垂直布局** `QVBoxLayout`:控件纵向排列 2. **水平布局** `QHBoxLayout`:控件横向排列 3. **网格布局** `QGridLayout`:按行列矩阵排列 4. **表单布局** `QFormLayout`:标签-输入框两列式布局 5. **分组布局** `QStackedLayout`:多页面切换布局[^2] #### 二、基础使用方法 ```cpp // 创建垂直布局并添加控件 QVBoxLayout *vLayout = new QVBoxLayout; vLayout->addWidget(new QPushButton("按钮1")); vLayout->addWidget(new QPushButton("按钮2")); // 设置窗口主布局 QWidget *window = new QWidget; window->setLayout(vLayout); ``` 可通过`addLayout()`实现布局嵌套: ```cpp QHBoxLayout *hLayout = new QHBoxLayout; hLayout->addLayout(vLayout); // 嵌套垂直布局 ``` #### 三、工作原理核心机制 1. **几何计算** 布局管理器通过`sizeHint()`获取控件理想尺寸,结合`minimumSizeHint()`计算最小需求空间[^4]。调整窗口时会触发: ```cpp item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); // 核心布局操作[^3] ``` 2. **拉伸策略** 通过`QSizePolicy`控制控件伸缩行为: ```cpp // 设置按钮水平扩展、垂直固定 button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); ``` 3. **自动调整** 布局管理器会自动处理: - 子控件的显隐状态变化 - 父窗口尺寸变化 - 系统字体/DPI变化 #### 四、高级配置技巧 1. **边距控制** ```cpp layout->setContentsMargins(20, 10, 20, 10); // 左、上、右、下边距 layout->setSpacing(15); // 控件间距 ``` 2. **比例分配** ```cpp // 设置两控件宽度比例为1:2 hLayout->addWidget(btn1, 1); hLayout->addWidget(btn2, 2); ``` 3. **固定尺寸控制** ```cpp widget->setMinimumSize(100,50); widget->setMaximumSize(300,200); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值