Qt布局中QCheckbox和QLineEdit水平布局中间没有空白,QCheckbox和QCombobox水平布局中间有很大的空白

目录

1.现象

[2.三个核心尺寸:SizeHint / MinimumSize / SizePolicy](#2.三个核心尺寸:SizeHint / MinimumSize / SizePolicy)

2.1.SizeHint(推荐尺寸,控件天然理想大小)

2.2.MinimumSize(最小尺寸下限)

2.3.SizePolicy(尺寸策略,决定多余空间怎么分配)

[3.Qt 常用控件默认 SizePolicy(水平 / 垂直)](#3.Qt 常用控件默认 SizePolicy(水平 / 垂直))

4.原因分析

5.解决方法


1.现象

代码:

cpp 复制代码
    QWidget* pParent = this;

    QWidget* pFirstWidget = new QWidget(pParent);
    QHBoxLayout* pFirstLayout = new QHBoxLayout(pParent);
    QCheckBox* pFirstCheckBox = new QCheckBox("111111", pParent);
    QLineEdit* pFirstLineEdit = new QLineEdit(pParent);
    pFirstLayout->addWidget(pFirstCheckBox);
    pFirstLayout->addWidget(pFirstLineEdit);
    pFirstWidget->setLayout(pFirstLayout);

    QWidget* pSecondWidget = new QWidget(pParent);
    QHBoxLayout* pSecondLayout = new QHBoxLayout(pParent);
    QCheckBox* pSecondCheckBox = new QCheckBox("222222", pParent);
    QComboBox* pSecondCombox = new QComboBox(pParent);
    auto p = pSecondCombox->sizePolicy();
    pSecondCombox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    pSecondCombox->addItem("3252352352");
    pSecondCombox->addItem("376677676");
    pSecondCombox->addItem("r78gge44g34");
    pSecondCombox->setCurrentIndex(0);
    pSecondLayout->addWidget(pSecondCheckBox);
    pSecondLayout->addWidget(pSecondCombox);
    pSecondWidget->setLayout(pSecondLayout);

    QVBoxLayout* pMainLayout = new QVBoxLayout(pParent);
    pMainLayout->addWidget(pFirstWidget);
    pMainLayout->addWidget(pSecondWidget);

    pParent->setLayout(pMainLayout);

2.三个核心尺寸:SizeHint / MinimumSize / SizePolicy

2.1.SizeHint(推荐尺寸,控件天然理想大小)

每个控件内部会计算一个刚好放下自身内容的尺寸:

  • QCheckBox:文字 + 方框的最小贴合尺寸
  • QComboBox:下拉按钮 + 默认显示文字的基础宽度
  • QLineEdit:默认预留给输入的基础宽度

布局排布时,优先以 SizeHint 作为基准尺寸

  • QLineEdit 的 SizeHint 很小,空间不够能缩到接近 0;
  • QComboBox / QSpinBox 的 SizeHint 本身偏大,且底层逻辑不允许小于该值。

2.2.MinimumSize(最小尺寸下限)

两层来源:

  • 控件内置硬最小尺寸(原生) QComboBox、QSpinBox、QDateEdit 自带原生最小宽度,哪怕你没手动设置 setMinimumWidth,系统也不允许控件比这个更小。 QLineEdit 原生最小宽度极小,几乎可以无限压缩。
  • 手动设置 setMinimumSize/setMinimumWidth,会覆盖原生下限。

2.3.SizePolicy(尺寸策略,决定多余空间怎么分配)

结合上面两个尺寸,策略分 4 种横向模式:

  • Fixed 尺寸永远等于 SizeHint,不能放大、不能缩小。CheckBox、RadioButton 默认。
  • Preferred 优先使用 SizeHint;有多余空间可放大,空间不足时允许缩小到 MinimumSize。
  • Expanding 和 Preferred 类似,但优先级更高,会主动抢夺布局剩余空白。 QLineEdit、QComboBox、SpinBox 默认都是 Expanding。
  • MinimumExpanding 以 MinimumSize 为基础,强制占满所有剩余空间,极少用。

3.Qt 常用控件默认 SizePolicy(水平 / 垂直)

| 控件 | 水平策略 | 垂直策略 | 关键特性 |

QWidget (基类) Preferred Preferred 所有控件的默认基础策略
QPushButton Preferred Fixed 随文字自适应,不会无限拉伸
QCheckBox Fixed Fixed 严格包裹文字,不扩张
QRadioButton Fixed Fixed 固定尺寸
QLineEdit Expanding Fixed 可无限拉伸,也能压缩变小
QComboBox Preferred Fixed 有最小宽度,不能过度收缩,极易留白
QSpinBox Preferred Fixed 和 ComboBox 行为一致,自带最小宽度
QDoubleSpinBox Preferred Fixed 同上
QDateEdit Expanding Fixed 不能随意压缩,容易产生布局空白
QTextEdit Expanding Expanding 双向充满剩余空间
QPlainTextEdit Expanding Expanding 双向充满剩余空间
QLabel Preferred Preferred 图片标签会尽量保持原图大小
QGroupBox Expanding Expanding 填满布局区域
QTableWidget Expanding Expanding 铺满父布局
QSlider (水平) Expanding Fixed 横向自动拉伸,高度固定
QSlider (垂直) Fixed Expanding 纵向自动拉伸,宽度固定

核心总结:

  • Fixed 类:CheckBox、RadioButton,大小卡死,只包裹自身内容。
  • Preferred 类:Button、普通 Label,按需扩张,不会霸占全部空白。
  • Expanding 且可压缩:QLineEdit,多余空间它吃掉,空间不足它缩小,布局不会留白。
  • Expanding + 不可压缩:ComboBox、SpinBox、DateEdit。

4.原因分析

1.CheckBox + QLineEdit

  • CheckBox:Fixed,固定 SizeHint 大小,不抢空间
  • LineEdit:Expanding,原生 MinimumSize 极小 布局宽度充足:空白全部拉伸给 LineEdit,两者紧贴无空隙; 布局宽度不足:LineEdit 收缩到很小,依然紧贴 CheckBox,无大片空白。

2.QCheckBox + QComboBox(出现大片空白根源)

  • CheckBox:Fixed,尺寸固定不变
  • ComboBox:Preferred + 原生 MinimumSize 很大,不能缩小 当布局总宽度 > CheckBox 宽度 + ComboBox 最小宽度: 多余空白会被分配给 Preferred的 ComboBox,但 ComboBox 不能缩小,空白就停留在两个控件中间; 窗口拉窄到极限,ComboBox 也不能低于自身最小宽度,间隙始终存在。

5.解决方法

改变一下显示策略即可:

cpp 复制代码
QComboBox* pSecondCombox = new QComboBox(pParent);
auto p = pSecondCombox->sizePolicy();
pSecondCombox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);