QT布局管理(3)--QLayout/QGridLayout/QFormLayout/QHBoxLayout以及sizeHint、sizePolicy

本文主要介绍QT布局管理中的两个关键知识点。一是sizeHint,它是QT对控件的推荐大小,多数控件有推荐值,且不受实际大小改变影响;二是sizePolicy,包含水平和垂直伸缩策略、伸展因子,部分策略的名称易产生误导。

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

最基本的布局管理,在设计师界面中可以看到:

各种布局类的继承关系:

QLayout布局QBoxLayout盒型布局QHBoxLayout 水平布局
QVBoxLayout 垂直布局
QFormLayout 两列布局 
QGridLayout 网格布局 
QStackedLayout 堆叠布局 

 

这些东西都是一目了然,不再赘述。

下面主要讲两个知识点:1、sizeHint,2、sizePolicy。这两个东西跟布局有密切关系,想随心所欲的设置布局,必须搞懂这俩东西。

1、sizeHint是所有QWidget都具有的一个属性,不过是只读的,通过sizeHint()函数。他代表的意义是,QT对该控件的推荐大小,也可以认为是控件的默认值。

帮助文档中说,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.(翻译:默认情况下,如果widget没有布局,则sizeHint()返回一个无效值,如果有布局,则返回推荐值)

我没理解,什么叫widget有布局,经过测试,QGroupBox是没有推荐值的,它的sizeHint()返回QSize(-1, -1),把QGroupBox放在布局中,返回值还是无效值QSize(-1, -1)。经过测试,大多数控件是有推荐值的,随便拖了几个控件出来,结果如下:

ui->pushButton->sizeHint() =  QSize(75, 23)
ui->groupBox->sizeHint() =  QSize(-1, -1)
ui->label->sizeHint() =  QSize(54, 12)
ui->tabWidget->sizeHint() =  QSize(114, 26)
ui->comboBox->sizeHint() =  QSize(69, 20)
ui->listView->sizeHint() =  QSize(256, 192)
ui->checkBox->sizeHint() =  QSize(71, 16)
ui->lineEdit->sizeHint() =  QSize(133, 20)
ui->textEdit->sizeHint() =  QSize(256, 192)

即使改变控件的实际大小,sizeHint也仍然保持上面的值不变。

2、sizePolicy

sizePolicy包含了水平伸缩策略、垂直伸缩策略、水平伸缩因子、垂直伸展因子,见下图:

水平、垂直伸展因子,就是设置占空的比例,例如水平方向共有3个控件,分别设置水平伸展因子为1、1、2,那么他们三个将在水平控件上各占25%、25%、50%。

 

关于水平伸缩策略、垂直伸缩策略QSizePolicy::Policy,从帮助文档抄来的表,做了翻译,如下:

  以下伸缩策略执行完之后,还要再被“最大最小尺寸”再次限定。也即,“伸缩策略”的优先权<“最大最小尺寸”
QSizePolicy::Fixed0不可伸缩,恒为QT的推荐值sizeHint()的大小。(注意,有些控件的推荐值为(-1,-1),该策略会导致不显示)
QSizePolicy::MinimumGrowFlag可伸缩,但是被限定了最小值为sizeHint,伸缩范围[hint,∞]
QSizePolicy::MaximumShrinkFlag可伸缩,但是被限定了最大值为sizeHint
QSizePolicy::PreferredGrowFlag | ShrinkFlag可伸缩,范围为[hint或小非0值,∞],伸长的优先权<Expanding,但是即使被挤也不会被挤扁成0,一般会被挤成sizeHint(有hint时),或者小方框(无hint时)
QSizePolicy::ExpandingGrowFlag | ShrinkFlag | ExpandFlag可伸缩,而且能伸就伸,
QSizePolicy::MinimumExpandingGrowFlag | ExpandFlag可伸缩,而且能伸就伸,但是被限定了最小值为sizeHint,伸长优先权=Expanding>Preferred
QSizePolicy::IgnoredShrinkFlag | GrowFlag | IgnoreFlag可伸缩,范围为[0,∞],区别在于不管有无hint,Ignored可以被挤扁为0。Minimum、Maximum、Preferred这三个只要>hint的空间,就不会来挤Ignored
注意:“最大最小尺寸”就是minimumSize()/maximumSize()/minimunWidth()等共6个,以上伸缩策略都是在最大最小尺寸区间内进行的
以下是真值
QSizePolicy::GrowFlag1具备>sizeHint的能力
QSizePolicy::ExpandFlag2尽可能的多占空
QSizePolicy::ShrinkFlag4具备<sizeHint的能力
QSizePolicy::IgnoreFlag8尽可能的多占空,但占空能力<ExpandFlag

尤其注意:

QSizePolicy::Minimum这个词有点误导人,看名字感觉像是打算令控件能多小就多小,实际上其意义却是:控件可伸可缩,但要限制其最小值。同类的误导词还有:QSizePolicy::Maximum。
QSizePolicy::Ignored这个词也很误导人,从名字上看,感觉像是让这个控件不参加伸缩,实际上其意义却是:忽略sizeHint的限制。

 

 

<think>嗯,用户想了解Qt布局管理器的使用方法和原理。首先,我需要回忆一下Qt布局管理器有哪些类型。根据引用[2],Qt提供了5种布局管理器,分别是QVBoxLayout、QHBoxLayoutQGridLayoutQFormLayout和QStackedLayout。这应该是基础知识,需要先介绍每种布局的作用。 然后,用户可能想知道如何使用这些布局。比如,如何在代码中创建和添加控件。可能需要举一个例子,比如垂直布局中添加按钮。记得提到addWidget和addLayout方法,这样用户可以知道如何嵌套布局。 接下来是工作原理部分。引用[3]提到布局管理器通过setGeometry来设置子部件的位置和大小。需要解释布局管理器在调整窗口大小时如何重新计算子部件的位置。同时,sizeHint和minimumSizeHint这些概念也很重要,需要说明它们的作用。 另外,引用[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); ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值